diff --git a/macosx/Info.plist b/macosx/Info.plist
index 5ebedcf70..2e923e315 100644
--- a/macosx/Info.plist
+++ b/macosx/Info.plist
@@ -12,12 +12,18 @@
com.newbreedsoftware.tuxpaint
CFBundleInfoDictionaryVersion
6.0
+ CFBundleName
+ Tux Paint
CFBundlePackageType
APPL
+ CFBundleShortVersionString
+ 0.9.18
+ CFBundleGetInfoString
+ 0.9.18, Copyright 2007, Tux Paint Development Team
CFBundleSignature
TXPT
CFBundleVersion
- 2006-10-18
+ 2007-12-17
NSMainNibFile
SDLMain
NSPrincipalClass
diff --git a/macosx/Read Me.txt b/macosx/Read Me.txt
index 302c14973..d11eda02c 100644
--- a/macosx/Read Me.txt
+++ b/macosx/Read Me.txt
@@ -1,10 +1,9 @@
Tux Paint Xcode 2.4 Project
notes by Martin Fuhrer
-This Tux Paint project file is located in a folder titled "macosx", which should in turn be placed in the root folder of the Tux Paint source code distribution. The project will then be able to access all the source code files. You will require Mac OS X 10.4 and XCode 2.4 or later to build this project.
-
-This XCode project has been configured under the assumption that you have certain libraries and files installed in particular locations under Mac OS X. This file indicates what you must install, and where these items go. Some of the libraries are installed via the Fink package manager, which can be downloaded from
+This Tux Paint project file is located in a folder titled "macosx", which should in turn be placed in the root folder of the Tux Paint source code distribution. The project will then be able to access all the source code files. You will require at least Mac OS X 10.4 and XCode 2.4 to build this project.
+This XCode project has been configured under the assumption that you have certain libraries and files installed in particular locations under Mac OS X. This documentation indicates what you must install, and where these items go. Some of the libraries can be installed via the MacPorts or Fink package managers. At the time of writing, MacPorts can install one additional required library (SDL Pango) that is not available in Fink, so I have written this document with MacPorts in mind. Several libraries are either misconfigured (with regards to building Tux Paint) or unavailable in MacPorts and Fink, and need to be configured, compiled, and installed manually. You will also need to create the following "sandbox" directory where you will build and store these libraries: /Users/Shared/tuxpaint
-- SDL --
@@ -18,14 +17,112 @@ SDL_ttf.framework
You can obtain the frameworks from the SDL website These frameworks contain both header files and libraries, and are copied into the Frameworks directory of the Tux Paint application bundle.
--- PNG, Internationalization, and Character Set Conversion Libraries --
+-- Installing Libraries via MacPorts --
-Install the PNG (libpng.a), GNU internationalization (libintl.a), and character set conversion (libiconv.dylib) libraries via Fink. By default, Fink will place the libraries in /sw/lib. These libraries will be statically linked into the Tux Paint binary.
+The following libraries can be installed via MacPorts.
+
+Library Install location
+
+GNU Internationalization: /opt/local/lib/libintl.a
+PNG: /opt/local/lib/libpng.a
+XML Parser: /opt/local/lib/libexpat.a
+Freetype: /opt/local/lib/libfreetype.a
+Cairo Vector Graphics: /opt/local/lib/libcairo.a
+SDL Pango: /opt/local/lib/libSDL_Pango.o
+
+The following MacPorts command will install all these libraries in one shot:
+% sudo port install libsdl_pango
+
+Copy all the static libraries listed above into the /Users/Shared/tuxpaint/lib directory, where the XCode project will find them. By keeping the static libraries in a separate directory, we will ensure that Tux Paint will not link against other dynamic libraries in /opt/local/lib (a problematic scenario if you wish to distribute your compiled version of Tux Paint to friends who most likely don't have these dynamic libraries installed). These libraries will be statically linked into the Tux Paint binary.
+-- Installing Libraries Manually --
+
+The following libraries require manual compilation and installation.
+
+Library Install location
+
+XML Font Configuration: /Users/Shared/tuxpaint/lib/libfontconfig.a
+GLib: /Users/Shared/tuxpaint/lib/libglib-2.0.a
+ /Users/Shared/tuxpaint/lib/libgobject-2.0.a
+ /Users/Shared/tuxpaint/lib/libgmodule-2.0.a
+Pango: /Users/Shared/tuxpaint/lib/libpango-1.0.a
+ /Users/Shared/tuxpaint/lib/libpangoft2-1.0.a
+SVG Scalable Vector Graphics: /Users/Shared/tuxpaint/lib/libsvg.a
+SVG Cairo: /Users/Shared/tuxpaint/lib/libsvg-cairo.a
+
+We will compile our libraries inside the "src" directory: /Users/Shared/tuxpaint/src
+and install the libraries in the "lib" directory: /Users/Shared/tuxpaint/lib
+
+XML Font Configuration:
+
+This library will already have been built and installed by MacPorts, but will not have been properly configured for Tux Paint. We need to reconfigure and build Fontconfig as follows:
+
+% cd /Users/Shared/tuxpaint/src
+% cp /opt/local/var/macports/distfiles/fontconfig/fontconfig*.tar.gz .
+% tar xzf fontconfig*.tar.gz
+% cd fontconfig*
+% sudo port deactivte fontconfig
+% ./configure --prefix=/Users/Shared/tuxpaint --enable-static --disable-shared --disable-docs --with-confdir=/Library/Application Support/TuxPaint/fontconfig/fonts --with-cache-dir=/Library/Application Support/TuxPaint/fontconfig/cache CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
+% make install
+% sudo port activate fontconfig
+
+GLib:
+
+MacPorts only installs the dynamic libraries for GLib. We need to reconfigure and build GLib with static libraries enabled as follows:
+
+% cd /Users/Shared/tuxpaint/src
+% cp /opt/local/var/macports/distfiles/fontconfig/fontconfig*.tar.gz .
+% tar xzf fontconfig*.tar.gz
+% cd fontconfig*
+% sudo port deactivate glib
+% ./configure --prefix=/Users/Shared/tuxpaint --enable-static CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib
+% make install
+% sudo port activate glib
+
+Pango:
+
+MacPorts only installs the dynamic libraries for Pango. We need to reconfigure and build Pango with static libraries enabled as follows:
+
+% cd /Users/Shared/tuxpaint/src
+% cp /opt/local/var/macports/distfiles/pango/pango*.tar.bz2 .
+% bunzip2 pango*.tar.bz2
+% tar xf pango*.tar
+% cd pango*
+% sudo port deactivate pango
+% ./configure --prefix=/Users/Shared/tuxpaint --enable-static CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib --with-included-modules=yes --with-dynamic-modules=no --disable-shared
+% make install
+% find . -name "*.a" -exec cp {} /Users/Shared/tuxpaint/lib/ \;
+% sudo port activate pango
+
+SVG Scalable Vector Graphics:
+
+Neither MacPorts nor Fink build and install the SVG library. You can retrieve sources from CVS via:
+http://webcvs.cairographics.org/libsvg/
+
+Assuming you place the sources in /Users/Shared/tuxpaint/src/libsvg, you can configure and build SVG as follows:
+
+% cd /Users/Shared/tuxpaint/src/libsvg
+% ./autogen.sh
+% ./configure --prefix=/Users/Shared/tuxpaint LIBSVG_CFLAGS=-I/usr/include LIBSVG_LIBS=-L/usr/lib --disable-shared
+% make install
+
+SVG Cairo:
+
+Neither MacPorts nor Fink build and install the SVG Cairo library. You can retrieve sources from CVS via:
+http://webcvs.cairographics.org/libsvg-cairo/
+
+Assuming you place the sources in /Users/Shared/tuxpaint/src/libsvg-cairo, you can configure and build SVG Cairo as follows:
+
+% cd /Users/Shared/tuxpaint/src/libsvg-cairo
+% ./autogen.sh
+% ./configure --prefix=/Users/Shared/tuxpaint LIBSVG_CAIRO_CFLAGS=-I/Users/Shared/tuxpaint/include LIBSVG_CAIRO_LIBS=-L/Users/Shared/tuxpaint/lib --disable-shared
+% make install
+
+
-- Universal and Cross Development --
-Tux Paint can be built for PowerPC, Intel, or both (as a universal binary). Since Tux Paint depends on a number of libraries, these libraries must also be built for the same platform(s) for which you wish to build Tux Paint. The latest versions of the SDL frameworks are universal binary and work fine regardless what platform(s) you want to build for. On the other hand, when Fink installs the PNG, internationalization, and character set conversion libraries, they are built only for the platform you are currently using. If you want to build a universal binary of Tux Paint, you will need to manually compile these libraries as universal binaries (see http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html for further information) and update the library paths (click on a library in Archives and choose File > Get Info).
+Tux Paint can be built for PowerPC, Intel, or both (as a universal binary). Since Tux Paint depends on a number of libraries, these libraries must also be built for the same platform(s) for which you wish to build Tux Paint. The latest versions of the SDL frameworks are universal binary and work fine regardless what platform(s) you want to build for. On the other hand, the libraries installed via MacPorts are built only for the platform you are currently using (MacPorts offers a universal build option, but in practise this fails for most libraries). If you want to build a universal binary of Tux Paint, you will need to manually compile these libraries as universal binaries (see http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html for further information) and update the library paths (click on a library in Archives and choose File > Get Info).
To set the target platform for your build:
1) Choose Project > Edit Active Target 'Tux Paint'
@@ -34,7 +131,7 @@ To set the target platform for your build:
4) Select the "Architectures" setting and click the Edit button.
5) Select PowerPC, Intel, or both.
-In order to allow the Tux Paint application to run on older versions of Mac OS X, it is necessary to compile and link against an older version of the Mac OS X SDK (eg. Mac OS X 10.2.8) using an older version of gcc (eg. gcc 3.3). Various versions of the Mac OS X SDKs and gcc can be installed from the XCode Installation DVD or disk image. Note that any libraries Tux Paint links against (eg. libraries installed by Fink) should also be compiled and linked against the same SDK, using the same version of gcc. Universal binary and Intel applications must be compiled using gcc 4.0 and the Mac OS X 10.4u SDK.
+In order to allow the Tux Paint application to run on older versions of Mac OS X, it is necessary to compile and link against an older version of the Mac OS X SDK (eg. Mac OS X 10.2.8) using an older version of gcc (eg. gcc 3.3). Various versions of the Mac OS X SDKs and gcc can be installed from the XCode Installation DVD or disk image. Note that any libraries Tux Paint links against (eg. libraries installed by MacPorts) should also be compiled and linked against the same SDK, using the same version of gcc. Universal binary and Intel applications must be compiled using at least gcc 4.0 and the Mac OS X 10.4(u) SDK.
To set the desired Mac OS X SDK:
1) Choose Project > Edit Project Settings
diff --git a/macosx/SDLMain.h b/macosx/SDLMain.h
index 7b2a67a2a..ae2284fb5 100755
--- a/macosx/SDLMain.h
+++ b/macosx/SDLMain.h
@@ -10,11 +10,21 @@
//#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_2
#import
+#import "TransparentTextView.h"
@interface SDLMain : NSObject
{
+ IBOutlet NSPanel *messagePanel;
+ IBOutlet NSTextField *messageText;
+ IBOutlet NSTextField *messageStatus;
+ IBOutlet NSProgressIndicator *messageProgress;
+ IBOutlet NSWindow *aboutWindow;
+ IBOutlet NSTextField *appnameText;
+ IBOutlet NSTextField *versionText;
+ IBOutlet TransparentTextView *acknowledgmentsText;
}
+- (IBAction)onAbout:(id)sender;
- (IBAction)onNew:(id)sender;
- (IBAction)onOpen:(id)sender;
- (IBAction)onSave:(id)sender;
@@ -29,4 +39,7 @@
- (void) sendSDLControlShiftKeystroke:(int)key;
- (void) setupBridge;
+- (void) displayMessage:(NSString*)message andStatus:(NSString*)status withProgressIndicator:(BOOL)progress;
+- (void) hideMessage;
+
@end
diff --git a/macosx/SDLMain.m b/macosx/SDLMain.m
index 33e3ea030..2a00f1268 100644
--- a/macosx/SDLMain.m
+++ b/macosx/SDLMain.m
@@ -11,6 +11,7 @@
#import
#import "macosx_print.h"
+#import "message.h"
#import "wrapperdata.h"
/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
@@ -46,6 +47,7 @@ static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
WrapperData macosx;
+SDLMain *sdlMain;
static NSString *getApplicationName(void)
{
@@ -70,6 +72,11 @@ static NSString *getApplicationName(void)
@end
#endif
+/* Category for NSFileManager */
+@interface NSFileManager (CreateDirectoryRecursively)
+- (BOOL)createDirectoryRecursively:(NSString *)path attributes:(NSDictionary *)attributes;
+@end
+
@interface SDLApplication : NSApplication
@end
@@ -82,7 +89,9 @@ static NSString *getApplicationName(void)
if (NSKeyDown == [anEvent type] || NSKeyUp == [anEvent type])
{
if( ( [anEvent modifierFlags] & NSCommandKeyMask ) == 0 )
+ {
return; // do not intercept keystrokes intended for SDL layer
+ }
}
}
[super sendEvent: anEvent];
@@ -131,6 +140,9 @@ static NSString *getApplicationName(void)
path = [@"~/Library/Application Support/TuxPaint" stringByExpandingTildeInPath];
[path getCString:(macosx.preferencesPath)];
+
+ path = @"/Library/Application Support/TuxPaint";
+ [path getCString:(macosx.globalPreferencesPath)];
}
-(void) fontsPath;
@@ -147,21 +159,53 @@ static NSString *getApplicationName(void)
/* The main class of the application, the application's delegate */
@implementation SDLMain
+- (IBAction) onAbout:(id)sender
+{
+ NSBundle *mainBundle = [NSBundle mainBundle];
+ NSDictionary *bundleInfo = [mainBundle infoDictionary];
+ NSMutableString *string;
+ NSMutableAttributedString *attributedString;
+ NSMutableDictionary *attributes;
+
+ /* string attributes */
+ NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
+ [paragraphStyle setAlignment:NSCenterTextAlignment];
+ attributes = [NSMutableDictionary dictionary];
+ [attributes setObject:[NSFont boldSystemFontOfSize:12] forKey:NSFontAttributeName];
+ [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
+ [paragraphStyle release];
+
+ /* display Tux Paint */
+ string = [bundleInfo objectForKey:@"CFBundleName"];
+ attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
+ [appnameText setAttributedStringValue:attributedString];
+ [attributedString release];
+
+ /* display version */
+ string = [NSMutableString stringWithString:@"Version "];
+ [string appendString:[bundleInfo objectForKey:@"CFBundleShortVersionString"]];
+ [string appendString:@" ("];
+ [string appendString:[bundleInfo objectForKey:@"CFBundleVersion"]];
+ [string appendString:@")"];
+ [versionText setStringValue:string];
+
+ /* display credits */
+ NSString *filePath = [mainBundle pathForResource:@"credits" ofType:@"txt"];
+ string = [NSString stringWithContentsOfFile:filePath];
+ [attributes setObject:[NSFont systemFontOfSize:10] forKey:NSFontAttributeName];
+ attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes];
+ [[acknowledgmentsText textStorage] setAttributedString:attributedString];
+ [attributedString release];
+ [acknowledgmentsText activateURLs];
+ [acknowledgmentsText setEditable:NO];
+
+ [aboutWindow makeKeyAndOrderFront:sender];
+}
+
+
- (IBAction) onNew:(id)sender
{
[self sendSDLControlKeystroke:SDLK_n];
- /*
- [NSApp beginSheet:nameWindow
- modalForWindow:[NSApp mainWindow]
- modalDelegate:nil
- didEndSelector:nil
- contextInfo:nil];
-
- [NSApp runModalForWindow:nameWindow];
-
- [NSApp endSheet:nameWindow];
- [nameWindow orderOut:self];
- */
}
- (IBAction) onOpen:(id)sender
@@ -246,6 +290,24 @@ static NSString *getApplicationName(void)
}
}
+- (void) displayMessage:(NSString*)message andStatus:(NSString*)status withProgressIndicator:(BOOL)progress
+{
+ [messageText setStringValue:message];
+ [messageStatus setStringValue:status];
+ [messagePanel makeKeyAndOrderFront:nil];
+ if (progress)
+ {
+ [messageProgress setUsesThreadedAnimation:YES];
+ [messageProgress startAnimation:nil];
+ }
+}
+
+- (void) hideMessage
+{
+ [messageProgress stopAnimation:nil];
+ [messagePanel close];
+}
+
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
@@ -268,7 +330,7 @@ static NSString *getApplicationName(void)
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
- [ aMenu sizeToFit ];
+ [aMenu sizeToFit];
}
#else
@@ -419,6 +481,40 @@ static void CustomApplicationMain (argc, argv)
[bridge preferencesPath];
}
+/* Install any required files from app bundle to destination */
+- (void) installFiles
+{
+ NSFileManager *fileManager = [NSFileManager defaultManager];
+ NSBundle *bundle = [NSBundle mainBundle];
+ BOOL fileExists = NO;
+
+ NSString *globalPreferencesPath = [NSString stringWithCString:(macosx.globalPreferencesPath)];
+ NSString *fontsPath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/fonts"];
+ NSString *cachePath = [globalPreferencesPath stringByAppendingString:@"/fontconfig/cache"];
+ NSString *fontsConfInstalledPath = [fontsPath stringByAppendingString:@"/fonts.conf"];
+ NSString *fontsDtdInstalledPath = [fontsPath stringByAppendingString:@"/fonts.dtd"];
+ NSString *fontsConfBundlePath = [bundle pathForResource:@"fonts" ofType:@"conf"];
+ NSString *fontsDtdBundlePath = [bundle pathForResource:@"fonts" ofType:@"dtd"];
+
+ fileExists = [fileManager fileExistsAtPath:fontsConfInstalledPath];
+ if (!fileExists) {
+ [fileManager createDirectoryRecursively:fontsPath attributes:nil];
+ [fileManager copyPath:fontsConfBundlePath toPath:fontsConfInstalledPath handler:nil];
+ }
+
+ fileExists = [fileManager fileExistsAtPath:fontsDtdInstalledPath];
+ if (!fileExists) {
+ [fileManager createDirectoryRecursively:fontsPath attributes:nil];
+ [fileManager copyPath:fontsDtdBundlePath toPath:fontsDtdInstalledPath handler:nil];
+ }
+
+ fileExists = [fileManager fileExistsAtPath:cachePath];
+ if (fileExists)
+ macosx.buildingFontCache = 0;
+ else
+ macosx.buildingFontCache = 1;
+}
+
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
@@ -467,6 +563,13 @@ static void CustomApplicationMain (argc, argv)
return TRUE;
}
+- (BOOL)textView:(NSTextView*)textView clickedOnLink:(id)link atIndex:(unsigned)charIndex
+{
+ BOOL success;
+ success = [[NSWorkspace sharedWorkspace] openURL: link];
+ return success;
+}
+
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
@@ -477,6 +580,9 @@ static void CustomApplicationMain (argc, argv)
/* Set up Cocoa to SDL bridge */
[self setupBridge];
+
+ /* Install any required files */
+ [self installFiles];
/* Set the working directory to the .app's parent directory */
[self setupWorkingDirectory:gFinderLaunch];
@@ -485,7 +591,8 @@ static void CustomApplicationMain (argc, argv)
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
-
+ sdlMain = self;
+
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main (gArgc, gArgv);
@@ -535,7 +642,35 @@ static void CustomApplicationMain (argc, argv)
@end
+@implementation NSFileManager (CreateDirectoryRecursively)
+- (BOOL)createDirectoryRecursively:(NSString *)path attributes:(NSDictionary *)attributes
+{
+ BOOL isDir = TRUE;
+ BOOL fileExists;
+
+ fileExists = [self fileExistsAtPath:path isDirectory:&isDir];
+ if (isDir) {
+ if (fileExists) {
+ /* directory exists */
+ return TRUE;
+ }
+ else
+ {
+ /* create directory */
+ NSString *parentDirectory = [path stringByDeletingLastPathComponent];
+ [self createDirectoryRecursively:parentDirectory attributes:attributes];
+ return [self createDirectoryAtPath:path attributes:attributes];
+ }
+ }
+ else
+ {
+ /* desired directory path is blocked by a file */
+ return FALSE;
+ }
+}
+
+@end
#ifdef main
# undef main
diff --git a/macosx/TransparentTextView.h b/macosx/TransparentTextView.h
new file mode 100644
index 000000000..0e3844854
--- /dev/null
+++ b/macosx/TransparentTextView.h
@@ -0,0 +1,32 @@
+//
+// TransparentTextView.h
+// Tux Paint
+//
+// Created by Martin Fuhrer on Wed Dec 12 2007.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+#import
+
+@interface TransparentTextView : NSTextView
+{
+}
+
+- (void)activateURLs;
+
+@end
diff --git a/macosx/TransparentTextView.m b/macosx/TransparentTextView.m
new file mode 100644
index 000000000..692b1942a
--- /dev/null
+++ b/macosx/TransparentTextView.m
@@ -0,0 +1,92 @@
+//
+// TransparentTextView.m
+// Tux Paint
+//
+// Created by Martin Fuhrer on Wed Dec 12 2007.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+#import "TransparentTextView.h"
+
+@implementation TransparentTextView
+
+- (void)drawViewBackgroundInRect:(NSRect)rect
+{
+}
+
+- (BOOL)isOpaque
+{
+ return NO;
+}
+
+- (void)activateURLs
+{
+ NSTextStorage* textStorage = [self textStorage];
+ NSString* string = [textStorage string];
+ NSRange searchRange = NSMakeRange(0, [string length]);
+ NSRange foundRange;
+
+ [textStorage beginEditing];
+ do
+ {
+ // assume that all URLs are enclosed between < >
+ foundRange = [string rangeOfString:@"<" options:0 range:searchRange];
+
+ if (foundRange.length > 0) //Did we find a URL?
+ {
+ NSURL* theURL;
+ NSMutableString* theURLString;
+ NSDictionary* linkAttributes;
+ NSRange endOfURLRange, range;
+
+ // restrict the searchRange so that it won't find the same string again
+ searchRange.location = foundRange.location + foundRange.length;
+ searchRange.length = [string length] - searchRange.location;
+
+ // assume the URL ends with >
+ endOfURLRange = [string rangeOfString:@">" options:0 range:searchRange];
+
+ // set foundRange's length to the length of the URL
+ foundRange.location++;
+ foundRange.length = endOfURLRange.location - foundRange.location;
+
+ // grab the URL from the text and format it properly
+ range = [[string substringWithRange:foundRange] rangeOfString:@"@"];
+ if (range.length > 0)
+ theURLString = [NSMutableString stringWithString:@"mailto:"];
+ else
+ theURLString = [NSMutableString stringWithString:@"http://"];
+ [theURLString appendString:[string substringWithRange:foundRange]];
+
+ // generate URL
+ theURL = [NSURL URLWithString:theURLString];
+
+ // make the link attributes
+ linkAttributes = [NSDictionary dictionaryWithObjectsAndKeys: theURL, NSLinkAttributeName,
+ [NSColor blueColor], NSForegroundColorAttributeName, nil];
+
+ // apply those attributes to the URL in the text
+ [textStorage addAttributes:linkAttributes range:foundRange];
+ }
+ }
+ while (foundRange.length != 0); //repeat the do block until it no longer finds anything
+
+ [textStorage endEditing];
+}
+
+@end
diff --git a/macosx/credits.txt b/macosx/credits.txt
new file mode 100644
index 000000000..e633b490c
--- /dev/null
+++ b/macosx/credits.txt
@@ -0,0 +1,11 @@
+(c) 2007 Tux Paint Development Team
+
+Website:
+
+
+Mac OS X build:
+Martin Fuhrer
+
+Universal binary made possible with assistance from:
+Carlo Gandolfi
+Douglas Barbieri
diff --git a/macosx/fonts.conf b/macosx/fonts.conf
new file mode 100644
index 000000000..d8c8b758f
--- /dev/null
+++ b/macosx/fonts.conf
@@ -0,0 +1,318 @@
+
+
+
+
+
+
+
+
+
+ /Library/Fonts
+ /Network/Library/Fonts
+ /System/Library/Fonts
+ /usr/X11R6/lib/X11/fonts/Type1
+ /usr/X11R6/lib/X11/fonts/TTF
+ /usr/share/fonts
+ ~/Library/Fonts
+ ~/.fonts
+
+ ~/.fontconfig
+
+
+
+
+
+ mono
+
+
+ monospace
+
+
+
+
+
+
+ sans serif
+
+
+ sans-serif
+
+
+
+
+
+
+ sans
+
+
+ sans-serif
+
+
+
+
+
+
+
+ Times
+ Times New Roman
+ Nimbus Roman No9 L
+ Luxi Serif
+ Kochi Mincho
+ AR PL SungtiL GB
+ AR PL Mingti2L Big5
+ Baekmuk Batang
+ serif
+
+
+
+ Lucida Grande
+ Geneva
+ Helvetica
+ Arial
+ Verdana
+ Nimbus Sans L
+ Luxi Sans
+ Osaka
+ Kochi Gothic
+ AR PL KaitiM GB
+ AR PL KaitiM Big5
+ Baekmuk Dotum
+ SimSun
+ sans-serif
+
+
+
+ Monaco
+ Courier
+ Courier New
+ Andale Mono
+ Luxi Mono
+ Nimbus Mono L
+ NSimSun
+ monospace
+
+
+
+
+ sans-serif
+
+
+ serif
+
+
+ monospace
+
+
+ sans-serif
+
+
+
+
+ ~/.fonts.conf
+
+
+ local.conf
+
+
+
+ Times
+ Times New Roman
+
+
+ Helvetica
+ Verdana
+
+
+ Arial
+ Verdana
+
+
+ Courier
+ Courier New
+
+
+
+
+ serif
+
+ Times New Roman
+ Nimbus Roman No9 L
+ Luxi Serif
+ Times
+ Kochi Mincho
+ AR PL SungtiL GB
+ AR PL Mingti2L Big5
+ Baekmuk Batang
+
+
+
+ sans-serif
+
+ Lucida Grande
+ Geneva
+ Verdana
+ Nimbus Sans L
+ Luxi Sans
+ Arial
+ Helvetica
+ Kochi Gothic
+ Osaka
+ AR PL KaitiM GB
+ AR PL KaitiM Big5
+ Baekmuk Dotum
+ SimSun
+
+
+
+ monospace
+
+ Monaco
+ Andale Mono
+ Courier New
+ Luxi Mono
+ Nimbus Mono L
+ Kochi Gothic
+ AR PL KaitiM GB
+ Baekmuk Dotum
+
+
+
+
+
+
+
+
+ roman
+
+
+
+ roman
+
+
+
+
+ matrix
+ 1.2
+ 01
+
+
+
+
+
+ oblique
+
+
+
+
+
+
+ 0x0020
+ 0x00a0
+ 0x00ad
+ 0x115f
+ 0x1160
+ 0x1680
+ 0x2000
+ 0x2001
+ 0x2002
+ 0x2003
+ 0x2004
+ 0x2005
+ 0x2006
+ 0x2007
+ 0x2008
+ 0x2009
+ 0x200a
+ 0x200b
+ 0x200c
+ 0x200d
+ 0x200e
+ 0x200f
+ 0x2028
+ 0x2029
+ 0x202a
+ 0x202b
+ 0x202c
+ 0x202d
+ 0x202e
+ 0x202f
+ 0x205f
+ 0x2060
+ 0x2061
+ 0x2062
+ 0x2063
+ 0x206A
+ 0x206B
+ 0x206C
+ 0x206D
+ 0x206E
+ 0x206F
+ 0x3000
+ 0x3164
+ 0xfeff
+ 0xffa0
+ 0xfff9
+ 0xfffa
+ 0xfffa
+
+
+
+ 30
+
+
+
+
diff --git a/macosx/fonts.dtd b/macosx/fonts.dtd
new file mode 100644
index 000000000..a5c54f983
--- /dev/null
+++ b/macosx/fonts.dtd
@@ -0,0 +1,222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/macosx/message.h b/macosx/message.h
new file mode 100644
index 000000000..4c0142b5e
--- /dev/null
+++ b/macosx/message.h
@@ -0,0 +1,27 @@
+//
+// message.h
+// Tux Paint
+//
+// Created by Martin Fuhrer on Sat Dec 8 2007.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+#define MSG_FONT_CACHE 1
+
+void displayMessage( int msgId );
+void hideMessage();
diff --git a/macosx/message.m b/macosx/message.m
new file mode 100644
index 000000000..010f513a7
--- /dev/null
+++ b/macosx/message.m
@@ -0,0 +1,55 @@
+//
+// message.m
+// Tux Paint
+//
+// Created by Martin Fuhrer on Sat Dec 8 2007.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+#import "SDLMain.h"
+#import "message.h"
+
+extern SDLMain* sdlMain;
+
+void displayMessage( int msgId )
+{
+ NSString *message = nil;
+ NSString *status = nil;
+
+ if( sdlMain == nil )
+ return;
+
+ switch( msgId )
+ {
+ case( MSG_FONT_CACHE ):
+ message = @"I'm currently fishing for fonts on your Mac. This may take me a minute, as I'd much rather be feeding on fish from the sea.";
+ status = @"Status: Caching fonts (this only needs to be done once)...";
+ [sdlMain displayMessage:message andStatus:status withProgressIndicator:YES];
+ break;
+ default:
+ break;
+ }
+}
+
+void hideMessage()
+{
+ if( sdlMain == nil )
+ return;
+
+ [sdlMain hideMessage];
+}
\ No newline at end of file
diff --git a/macosx/speech.h b/macosx/speech.h
new file mode 100644
index 000000000..64e6e6164
--- /dev/null
+++ b/macosx/speech.h
@@ -0,0 +1,25 @@
+//
+// speech.h
+// TuxPaint
+//
+// Created by Martin Fuhrer on 13/12/07.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+void speak_string(const wchar_t *str);
+
diff --git a/macosx/speech.m b/macosx/speech.m
new file mode 100644
index 000000000..07ae787c6
--- /dev/null
+++ b/macosx/speech.m
@@ -0,0 +1,51 @@
+//
+// speech.m
+// TuxPaint
+//
+// Created by Martin Fuhrer on 13/12/07.
+// Copyright (c) 2007 Martin Fuhrer.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+// (See COPYING.txt)
+//
+
+#import
+#import "speech.h"
+#import "i18n.h"
+
+void speak_string(const wchar_t *widecharString)
+{
+ char multibyteString[1024];
+ NSString *string = [NSString string];
+
+ // speech synthesizer can pronounce only English phonemes and syllables
+ int lang = get_current_language();
+ if( lang != LANG_EN && lang != LANG_EN_GB && lang != LANG_EN_ZA )
+ return;
+
+ NSArray *voices = [NSSpeechSynthesizer availableVoices];
+ NSSpeechSynthesizer *synthesizer = [[NSSpeechSynthesizer alloc] init];
+
+ wcstombs(multibyteString,widecharString,sizeof(multibyteString));
+ if( [string respondsToSelector:@selector(string:stringWithCString:encoding:)] )
+ string = [NSString stringWithCString:multibyteString encoding:NSUTF8StringEncoding];
+ else
+ string = [NSString stringWithCString:multibyteString];
+
+ // speak string using a random voice
+ [synthesizer setVoice:[voices objectAtIndex:rand()%[voices count]]];
+ [synthesizer startSpeakingString:string];
+ [synthesizer release];
+}
\ No newline at end of file
diff --git a/macosx/tp_magic_api.h b/macosx/tp_magic_api.h
new file mode 100644
index 000000000..c2f758165
--- /dev/null
+++ b/macosx/tp_magic_api.h
@@ -0,0 +1,138 @@
+#ifndef TP_MAGIC_API_H
+#define TP_MAGIC_API_H
+
+#include "SDL.h"
+#include "SDL_mixer.h"
+
+
+/* min() and max() variable comparisons: */
+
+#ifdef __GNUC__
+// This version has strict type checking for safety.
+// See the "unnecessary" pointer comparison. (from Linux)
+#define min(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x < _y ? _x : _y; })
+#define max(x,y) ({ \
+ typeof(x) _x = (x); \
+ typeof(y) _y = (y); \
+ (void) (&_x == &_y); \
+ _x > _y ? _x : _y; })
+#else
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+
+/* clamp() returns 'value', unless it's less than 'lo' or greater than 'hi',
+ in which cases it returns 'lo' or 'hi', respectively: */
+
+#define clamp(lo,value,hi) (min(max(value,lo),hi))
+
+
+/* Flags you can send to 'special_notify' */
+
+/* The image has been mirrored (so starter should be, too) */
+/* (as of API version 0x00000001) */
+
+#define SPECIAL_MIRROR 0x0001
+
+/* The image has been flipped (so starter should be, too) */
+/* (as of API version 0x00000001) */
+#define SPECIAL_FLIP 0x0002
+
+
+typedef struct magic_api_t {
+ /* A string containing the current version of Tux Paint (e.g., "0.9.18") */
+ char * tp_version;
+
+ /* A string containing Tux Paint's data directory
+ (e.g., "/usr/local/share/tuxpaint/") */
+ char * data_directory;
+
+ /* Call to have Tux Paint draw (and animate) its progress bar */
+ void (*update_progress_bar)(void);
+
+ /* Call to request special events; see "SPECIAL_..." flags, above */
+ void (*special_notify)(int);
+
+ /* Converts an RGB byte to a linear float */
+ float (*sRGB_to_linear)(Uint8);
+
+ /* Converts a linear float to an RGB byte */
+ Uint8 (*linear_to_sRGB)(float);
+
+ /* Returns whether an (x,y) location is within a circle of a particular
+ radius (centered around the origin: (0,0)); useful for creating tools
+ that have a circular 'brush' */
+ int (*in_circle)(int,int,int);
+
+ /* Receives an SDL pixel value from the surface at an (x,y) location;
+ use "SDL_GetRGB()" to convert the Uint32 into a Uint8 RGB values;
+ NOTE: Use SDL_LockSurface() on the surface before doing (a batch of)
+ this call! Use SDL_UnlockSurface() when you're done.
+ SDL_MustLockSurface() can tell you whether a surface needs to be locked. */
+ Uint32 (*getpixel)(SDL_Surface *, int, int);
+
+ /* Assigns an SDL pixel value on a surface at an (x,y) location;
+ use "SDL_MapRGB()" to convert a triplet of Uint8 RGB values to a Uint32;
+ NOTE: Use SDL_LockSurface() on the surface before doing (a batch of)
+ this call! Use SDL_UnlockSurface() when you're done.
+ SDL_MustLockSurface() can tell you whether a surface needs to be locked. */
+ void (*putpixel)(SDL_Surface *, int, int, Uint32);
+
+ /* Asks Tux Paint to play a sound (one loaded via SDL_mixer library);
+ the first value is for left/right panning (0 is left, 128 is center,
+ 255 is right); the second value is for total volume (0 is off, 255 is
+ loudest) */
+ void (*playsound)(Mix_Chunk *, int, int);
+
+ /* Asks Tux Paint to stop playing the sound played by 'playsound()' */
+ void (*stopsound)(void);
+
+ /* Asks Tux Paint to calculate a line between (x1,y1) and (x2,y2);
+ every 'step' iterations, it will call your callback function
+ (which must accept a 'magic_api *' Magic API pointer and 'which' integer
+ for which tool is being used, the 'last' and current ('canvas')
+ SDL_Surfaces, and an (x,y) position) */
+ void (*line)(void *, int, SDL_Surface *, SDL_Surface *, int, int, int, int, int, void (*)(void *, int, SDL_Surface *, SDL_Surface *, int, int));
+
+ /* Returns whether the mouse button is down */
+ int (*button_down)(void);
+
+ /* Converts RGB bytes into HSV floats */
+ void (*rgbtohsv)(Uint8, Uint8, Uint8, float *, float *, float *);
+
+ /* Converts HSV floats into RGB bytes */
+ void (*hsvtorgb)(float, float, float, Uint8 *, Uint8 *, Uint8 *);
+
+ /* Holds Tux Paint's canvas dimensions */
+ int canvas_w;
+ int canvas_h;
+
+ /* Returns a new surface containing the scaled contents of an input
+ surface, scaled to, at maximum, w x h dimensions
+ (keeping aspect ratio, if requested; check the return surface's
+ 'w' and 'h' elements to confirm the actual size) */
+ SDL_Surface * (*scale)(SDL_Surface *, int, int, int);
+
+ /* Returns whether a particular position of the canvas has been labeled
+ as 'touched,' since the mouse was first clicked; this function ALSO
+ assigns the position as touched, until the next time the mouse is
+ clicked; useful for not applying the same effect from 'last' to 'canvas'
+ more than once per click-and-drag sequence */
+ Uint8 (*touched)(int, int);
+} magic_api;
+
+
+/* The version of the Tux Paint Magic tool API you are being compiled
+ against. Your 'XYZ_api_version()' should return this value.
+ If Tux Paint deems you compatible, it will call your 'XYZ_init()' (etc.)
+ and you will be active. */
+
+#define TP_MAGIC_API_VERSION 0x00000001
+
+#endif
+
diff --git a/macosx/wrapperdata.h b/macosx/wrapperdata.h
index 34f29c7a1..b41cdb2a5 100644
--- a/macosx/wrapperdata.h
+++ b/macosx/wrapperdata.h
@@ -14,14 +14,16 @@
struct WrapperDataStruct
{
- char dataPath[2048]; // path to data folder inside Tux Paint application bundle
- char preferencesPath[2048]; // path to the user's Tux Paint preferences folder
- char fontsPath[2048]; // path to the user's fonts folder
- int foundSDL; // was SDL.framework found?
- int foundSDL_image; // was SDL_image.framework found?
- int foundSDL_mixer; // was SDL_mixer.framework found?
- int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper?
- int menuAction; // was the action initiated by a Mac OS X menu selection?
+ char dataPath[2048]; // path to data folder inside Tux Paint application bundle
+ char preferencesPath[2048]; // path to the user's Tux Paint preferences folder
+ char globalPreferencesPath[2048]; // path to all users' Tux Paint preferences folder
+ char fontsPath[2048]; // path to the user's fonts folder
+ int buildingFontCache; // is the FontConfig font cache currently being built?
+ int foundSDL; // was SDL.framework found?
+ int foundSDL_image; // was SDL_image.framework found?
+ int foundSDL_mixer; // was SDL_mixer.framework found?
+ int cocoaKeystrokes; // should keystrokes be intercepted by Cocoa wrapper?
+ int menuAction; // was the action initiated by a Mac OS X menu selection?
};
typedef struct WrapperDataStruct WrapperData;