Tuesday, January 27, 2009

A temporary fix for Hindi (Devanagari) on the iPhone

As I explained in my last post, the Devanagari rendering situation on the iPhone is dead on arrival. To wit, the chhoti-I matra (the vowel ‘i’ as in kick) is always rendered one position to the right of its conventional placement.

While explaining the problem to a keen-eared buddy this evening, it occurred to me that there was a simple fix ad hoc:

shift the chhoti-I matra one position to the left in the encoding

This is just fixing the symptom but there’s nothing else to be done (short of providing one’s own font engine) while we wait for Apple to fix this in the firmware. In any case, the lack of any symptoms is all that the discerning public cares for.

I’d remember to check for firmware version to be at most 2.2 with a message to [[UIDevice currentDevice] systemVersion], and remember to update things accordingly when the next firmware version is released.

Xcode:


iPhone simulator (correct - for now):

Wednesday, January 21, 2009

Hindi is broken on iPhone (as of 2.2)

This afternoon I decided to wrap the (public-domain) text of a Hindi short story (by) in a little application to run on my iPod Touch, as what you might call a standalone e-book. I hadn’t really done any Hindi browsing on the device so far but when I’d first tried it I had easily managed to rename a well-known Hindi song successfully from ‘Mere Mehboob’ to , and it’d showed as such on the iPod.

So, naturally, I was encouraged and had expected things to go smoothly with the little ebook app.

Fail! The Devanagari script (Hindi as it is written) is badly broken on the iPhone platform. The chhoti-I matra, the short ‘i’ sound as in kick does not render correctly at all.

It should be before the consonant to which it is attached:

It renders instead as follows, after the consonant:


This is not a valid expression in Devanagari. It is lamentable that Apple went far enough to support the script at all and then neglected this little show-stopper at the tail end. Especially because it works well on OS X and you’d think they’d share some tests with the iPhone platform.

Xcode (correct):

iPhone simulator (incorrect):


You could disregard this and get by with a mental re-ordering of the I-matra if you must, but it’s still not what you’d expect in an Apple device.

Tuesday, January 6, 2009

Use the Mac's accelerometer in the iPhone Simulator


The accelerometer is not simulated in the current iPhone SDK (for iPhone OS 2.2).

Otto Chrons has posted a
neat package that sends accelerometer data from an iPhone or iPod Touch to an application running in the iPhone simulator. This package is in two parts: a ‘server’ that runs on your iPhone hardware and a ‘client’ in the form of source code that you can drop into your project (adding just an #import statement).

This works really well, except when:
1) you don’t have an iPhone or iPod Touch, or
2) you’re not registered in the Standard or Enterprise iPhone Development programme; I wasn’t registered at the time, and so I had no way to push Otto’s server application to my iPod Touch.

But then it occurred to me that my MacBook did have an accelerometer. If only that could serve data to the fake accelerometer in the simulator... So I looked, and providentially enough,
UniMotion hove into view.

So I browsed the source for the two packages for a bit, with a view to nefarious smash-and-grab, but by more happy chance it turned out that the relevant pieces in both were modular enough to fit as they were, with a little python for glue.

Otto’s client expects a string with timestamp and x,y,z readings over UDP, and UniMotion’s
motion is kind enough to spew x, y and z readings to standard output, though they’re not oriented in the same directions as those in the iPhone SDK’s UIAcceleration.

On my late 2006 MacBook,
motion emits x,y,z with a positive magnitude to the left, towards me and downwards, respectively. UIAcceleration expects readings to be positive to the right, away from me and upwards, respectively.

So all I needed to do was to grab
motion’s output (with the -f flag for acceleration in units of G), multipy each value by -1, add a timestamp and broadcast over UDP on the given port in the format that Otto’s client expects. I did need to run calibrate in the UniMotion suite first.

Here’s my python glue:


import sys, socket, time, traceback

kCFAbsoluteTimeIntervalSince1970 = 978307200.0 # from CFDate.c

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('',0))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

while 1:
  try:
    line = sys.stdin.readline()[:-1] # read line and strip EOL
    fields = line.split() # split around space character
    floatfields = map(float, fields) # convert to floats

    # transform co-ordinate system, from SMS- to UIAcceleration-format,
    # for my macbook (late 2006)
    x, y, z = map(lambda x: -1 * x, floatfields)

    # change epoch to be compatible with CFAbsoluteTimeGetCurrent()
    currentTime = time.time() - kCFAbsoluteTimeIntervalSince1970

    accdata = ','.join(map(str,('ACC: 0',currentTime,x,y,z)))

    sock.sendto(accdata, ('<broadcast>', 10552))
    # print '% .2f % .2f % .2f' % (x, y, z)
  except (ValueError, KeyboardInterrupt):
    sock.close()
    sys.exit(-1)
  except:
    traceback.print_exc()


I call this
sendaccsim.py and run it as:
$ ./motion -f 17 | python sendaccsim.py

It’s just a bit awkward swinging the Mac around like a tea tray.