NSImage setSize and setScaleWhenResized

19 07 2008

The setSize of NSImage behaves differently on the Leopard and the Tiger.
According to the NSImage class reference for the Leopard, it says :

“Changing the size of an NSImage after it has been used effectively resizes the image.”

It behaves as such on the Leopard, but not on the Tiger.
On the Tiger, the setSize doesn’t resize an image.

Take a look at the source code below.


NSImage *anImage;
NSSize imageSize;
NSString *imagePath;

imagePath = [[NSBundle mainBulde] pathForImageResource:@"myLogo.eps"];
anImage = [[NSImage alloc] initWithContentsOfFile:imagePath];
imageSize = [anImage size];
imageSize.width *= 0.3;
imageSize.height *= 0.3;
[anImage setScaleWhenResized:YES]; // For the Tiger
[anImage setSize:imageSize];

The eps format is a postscript format with which a scaling can be used.
The Leopard version of the setSize method of the NSImage automatically scales and draws the image as such.
However, on the Tiger the setScaleWhenResized with YES as its parameter should be explicitly called.
Documentation for the Tiger explains this much better.

For other approaches, Sci-Fi Hi-Fi hosted a good article.





Differences in function name decoration for the Leopard and pre-Leopard

18 07 2008

From the Mac OS X 10.5, or the Leopard, the function name decoration for standard C functions were changed. It is not only for the Mac, but also for other Unices also.
When I took over other’s project, he set the SDK to use to MAC OS X 10.5 on the Xcode project setting, while he set the Deployment target to Mac OS X 10.4.
The reason was that there was an external library built from a console, and with the 10.4 SDK it threw linking errors like :

_fnctl$UNIX2003 can’t be found

Why? Because it uses the external library was built without the -mmacosx-version-min=10.4, it is linked to standar library with the new convention for which $UNIX2003 postfix is appended.
( Please cf. my previous post on building universal binary for configure based Unix project for this. Apple didn’t update their tech note page for the Leopard.)

So, if you want to build external libraries from the console, try this instead :

export CFLAGS=”-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -mmacosx-version-min=10.4
export LDFLAGS=”-arch i386″
sudo ./configure –prefix=/opt/local –disable-dependency-tracking

I should mention two important things here.

1. If you build it on a Tiger machine, you don’t need to use the -mmacosx-version-min=10.4. It will use the latest version as its base target.
So, it is linked for the Tiger. However, if you build the source code on a Leopard machine, you should use the option. You may shout, “Of course”, here.

2. Please take a look at the first two lines where the CFLAGS and LDFLAGS are set. I used only -arch i386. They were set on a Leopard machine. There was something odd on a Tiger machine to build a Universal Binary version of the external library.
I expected that it is OK and enough to use “-arch i386 -arch ppc” to build a Universal Binary version of the library.

However, I found out that the generated Intel binary code on a PPC Tiger was different from that built on a Intel Leopard machine. They stripped codes differently. So, on the Tiger machine, the compiler stripped its static functions more aggressively for the Intel architecture.

So, I had to build a PPC version on a PPC Tiger machine and an Intel version on a Intel Leopard machine separately and combined them using the lipo.
(Is there any switch which controls how much it strips codes? Why the default behaviour is so different? I tried fidning those at the GCC web site, but I couldn’t find one unfortunately.)

Also, the PowerPC binary generated on a Intel Leopard looked different from that on a PPC Tiger machine. That is why I asked question, “[Q] Is the 10.4u SDK distributed for the Intel Mac and the PPC Mac different?”, to the cocoa mailing list around July, 27, 2008.

So, let’s go back to the topic where we started.
So, by compiling the external library correctly, you can change the SDK setting on the Project setting to Mac OS X 10.4, and it compiles successfully.
I would like to mention, especially to Xcode beginners, that the Deployment Target setting should be used carefully and it is not for targeting some specific version of Mac OS X when a highest version of the Mac OS X SDK is used.
I don’t like the name, “Deployment Target”. It misleads people very easily. It is sort of “Deployment Target”, but it is different from what people can easily imagine what it is for.

Almost all people upgraded from 10.0 through 10.3 Panther to 10.4 Tiger.
Because the 10.4 Tiger is quite complete version compared to its predecessors and quite reliable, I think there are still many companies which make their product for the Tiger.
Indeed, it is better to write programs which can run on the Tiger and the Leopard at the same time without changing the source codes.
(It is one of the reason I don’t use Objective-C 2.0 addition.) The Panther is also a stable version. I don’t know how many people still use the 10.3 Panther.
Apple still provides 10.3 SDK for the latest XCode 3.1. So, I guess there are still many.
But in my case I’m OK to consider only the 10.4. Anyway, point is that it is better to keep old machines for development and test purpose.
My 1Ghz iMac 17″ machine is still my main machine and it handles playing movies while it is downloading Korean soap operas and “History Special” program using P2P.
At the same time, I write codes on it and check email. The PowerPC tends to have better throughput, so it handles all of those very nicely and smoothly.
The only exception is to play HD clips with huge dimension and VC-1 clips. (Probably it is because the VC-1 decoder from the ffmpeg is not optimized enought yet.)
So, there are many good reason to keep the old machine!





Poll : Who read articles here at JongAm’s blog?

15 07 2008

Hello, all.

I was quite busy recently and had no chance to post any new story here.

I had things to write but I doubt if I can even remember them. :)

By the way, I would like to know who read my post and what you do.

I do notice some Koreans visit by looking at the search terms. Are you a Korean living in the US? Or visiting from Korea? What do you think about my blog? Do you want Windows stuff or Mac stuff? Or even Unix stuff?

Do you want some development related gossip or idea as well as things about coding?

Is there anything you want to tell me?

I appreciate any comment except for some flames.

Updated : OK.. So, han9kin is the only one who visit my site! And others can be just bots. The number of visitors monthly exceeds 1000 now, so I wanted to know who are interested in my blog and what they expected and how they think about it, i.e. my bad English, and so on. If there are people who want to leave any comment, I welcome you always!





NSViewController

15 07 2008

NSViewController was introduced from the Leopard, but even Apple’s document doesn’t explain why it was added and what it is for.

Here at KATI blog, there is a good background information on the NSViewController.

NSViewController, the New C in MVC - Pt. 1 of 3

NSViewController, the New C in MVC - Pt. 2 of 3

NSViewController, the New C in MVC - Pt. 3 of 3

I would like to thank  Stefan Arentz, who told me about the link and also to Cathy Shive who is the owner of the KATI blog for the good article.





Building a library in Universal Binary format

27 06 2008

The Apple Inc. put nice documents on building a Unix program as a Universal Binary format.

The 1st one is for Unix geek, while the 2nd one is for IDE addicts.
Each has its own pros and cons.
    The 1st one doesn’t require a project to be converted. However, it is pretty hard to figure out what is going on and what started being wrong. Things are scrolled up and text is written in the screen without any indentation or separation based on context.
    The 2nd one, on the other hand, uses the Xcode to compile. However, the Xcode just works as a shell to the configure script. You are making just a dummy project in which a script to invoke ./configure is in. What is more important aspect fundamentally here is that the 1st approach tries compile the source codes in one step. In its CFLAGS and LDFLAGS, you issue -arch ppc -arch i386. So, the gcc compiles source codes in combination of the two. And you don’t need a “merge” stage. However, the 2nd approach let the gcc compile and link the sources and the objects files for each architecture. You need to invoke the lipo to tie the two generated library or executable. 
Which one do you like more? Well..as for the lipo approach, you can do it in the console also. So, you need to choose one according to convenience of building. Yeah.. the 1st approach seems to be easier. However, some open source projects cannot be built by the 1st approach. For example, the postgreSQL can’t be built by the 1st approach. It fails in compiling. I don’t know why. But somewhere I heard that they way the gcc optimize codes is different for the two approach.
    There is the 3rd one. It requires you some time to reorganize the source code structure or directory structure. (Not necessarily) So, you need to understand each and every configure script and Makefile contents. What you do here is to make a genuine Xcode project. Once things are done, it is much trouble-free than the 1st and the 2nd approach, because information is located where it can be easily found, like the property of projects, etc. Some people don’t like IDE-centric approach like this 3rd one. They usually say that it is inconvenient for batch-building. Well… not true. You can issue build command in a console window without running the Xcode.
OK, so far we thought about 3 ways of building very Unix-like project.
Now, I would like to fix something described in the Apple document.
For the 1st document mentioned above, there is something wrong for Leopard-era.

env CFLAGS=”-O -g -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc” \
LDFLAGS=”-arch i386 -arch ppc” ./configure –prefix=${HOME}/Hello –disable-dependency-tracking

    You need to add -mmacosx-version-min=10.4, for example to the CFLAGS. On Leopard Intel Mac, the resultant binary size is very different from the case without the option, although the source code doesn’t use any Cocoa/Carbon framework. In default, the 10.5 leopard gcc seems to strip codes more aggressively. So, for some static functions, they can be removed although they are actually used.   Another thing I would like to mention is the -isysroot /Developer/SDKs/MacOSX10.4u.sdk.
What the option means is that it will use the 10.4 universal SDK. It is very important to determine what version of the MacOS X is targetted. Even when the open source project doesn’t use any Cocoa functions, it is better to include that option. You can easily see that the file size is different between the two cases with and without the option.    

As a closure, I would like to mention that the 10.4u SDK seems to be different on PPC mac and Intel Mac. Although they are all 10.4u SDK, the result of compilation seems to be different. the one distributed with/for  Intel Mac doesn’t seem to be correct sometimes. I need to confirm this.

 





$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)

21 06 2008

What is this? I found this setting in some project files obtained from someone else.

It sounds like that… The Xcode will support more than the Intel and PowerPC processors?





On Interface Building..

21 06 2008

    Probably I’m just the last one who find KATI : Developing Interfaces with Cocoa. I did not read the whole post yet, but I could feel that it is full of very good information.

I would like to put the link to the right side of my blog.

It is worth while to reading it!

 





A few lines on how to use the NSXMLDocument

21 06 2008

        Because I needed to retrieve information from a Final Cut Pro project file saved in XML format, I wrote some lines of code. But before doing so, to figure out what XQuery statement to use, I implemented a helper program to load a XML document and test some XQuery statement. Apple’s XMLBrowser sample was helpful, but it doesn’t show an input XML file and the result of XQuery side by side. 

        So, I wrote one, and here I would like to the quick and dirty approach on how to use the NSXMLDocument.

        The NSXMLDocument is a tree parser, while the Apple also provides an event parser. The tree parser provides very helpful method to manipulate an XML file. One of the good thing is XQuery. So, in this short codes, it sends query to the NSXMLDocumet.


- (IBAction)openXMLFile:(id)sender
{
    int result;
    NSArray *filetypes = [NSArray arrayWithObject:@"xml"];
    NSOpenPanel *oPanel = [NSOpenPanel openPanel];

    [oPanel setAllowsMultipleSelection:NO];

    result = [oPanel runModalForDirectory:NSHomeDirectory() file:nil types:filetypes];
    if ( result == NSOKButton) {
        NSString *aFile = [oPanel filename];
        [self createXMLDocumentFromFile:aFile];
        [sourceTextView setString:[NSString stringWithFormat:@"%@", xmlDoc]];
    }

}

- (void)createXMLDocumentFromFile:(NSString *)file
{
    NSError *err = nil;

    NSURL *furl = [NSURL fileURLWithPath:file];
    if( !furl )
    {
        NSLog(@"Can't create an URL from file %@.", file );
        return;
    }

    if( xmlDoc )
        [xmlDoc release];

    xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:furl options:(NSXMLNodePreserveWhitespace|NSXMLNodePreserveCDATA) error:&err];
    if( xmlDoc == nil )
    {
        // in previous attempt, it failed creating XMLDocument because it
        // was malformed.
        xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:furl options:NSXMLDocumentTidyXML error:&err];
    }
    if( xmlDoc == nil)
    {

        NSLog( @"Error occurred while creating an XML document.");
//        if(err)
//            [self handleError:err];
    }
    else
        NSLog(@"%@", xmlDoc);
}

And… here is the code to send XQuery statement to the NSXMLDocument


- (IBAction)executeQuery:(NSButton *)sender {

    [queryResultView setString:@""];

    if ([queryTextView string] != nil) {
        NSError *error;
        NSArray *result = [xmlDoc objectsForXQuery:
             [queryTextView string] constants:nil error:&error];
        if (result) {
            unsigned count = [result count];
            unsigned i;
            NSMutableString *stringResult = [[NSMutableString alloc] init];
            for (i = 0; i < count; i++) {
                [stringResult appendString:
                    [NSString stringWithFormat:@"%d: {\r", i]];
                [stringResult appendString:[[result objectAtIndex:i]
                    description]];
                [stringResult appendString:@"\r}\r"];
            }
            [queryResultView setString:stringResult];

            NSLog(@"%@", stringResult);

            [stringResult release];
        } else if (error) {
            NSLog(@"Error Occurred.");

            //[self handleError:error];
        }

    }

}




How to enable Font and Format menu with the Interface Builder 3

16 06 2008

    Within the MacOS X 10.5 Leopard there are a lot of new features included. Nobody, even the Apple, can’t enlist the feature set. They are from small enhancement to big additions. For example, the new dictionary can now be linked to some Korean dictionary, and so on. It searches words from the Wikipedia.

    However, no one seems to talk about the new additions in the Cocoa/Carbon framework or even the development tools. Cocoa Scripting Bridges, and so on.. There are lots of new things added. Some are new. But there are also something becoming bad.

    I didn’t care about the Font menu and Format menu before. Because those things are free bread for the Cocoa programming. Until the Interface Builder 2.x, you can just drag & drop those menus in your main menu bar, and it automatically supported font manipulation in any of your NSTextView.

    However, from the Interface Builder 3.0, it is not true anymore. You need to connect message handlers for yourself, although you still don’t need to write a single line of codes. I don’t understand this. The FirstResponder supports all the required messages for the Font and the Format menus, just like it did during the Interface Builder 2.0 era. 

    Anyway, Apple posted a technical article on that here.

 





Tutorials for XQuery and Cocoa

14 06 2008

    I needed to extract information from a Final Cut Pro project file in XML format. There are two ways to do so. One is to use a event-driven method using NSXMLParser, while the other approach is to use a Tree parser like NSXML.

    Apple provides a nice sample code for XML processing, which is located at /Developer/Examples/Foundation/XMLBrowser.
With this sample, you can apply many settings like “Pretty-Print” and so on. You can even try what result XQuery statement returns. So, this XMLBrowser sample code is quite a good test bed for your Objective-C/Cocoa coding.

    Along this, I found a good tutorial for the XQuery. ( You can understand the XQuery to XML as SQL to the relational database. ) There is another one here at the IBM developer works.

    Also, Apple provides a very interesting tips for the Final Cut.

Enjoy the XML coding!!!