<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>LockFocus</title>
	
	<link>http://likethought.com/lockfocus</link>
	<description>Exploring Graphics in Cocoa</description>
	<lastBuildDate>Fri, 23 Oct 2009 00:25:35 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/lockfocus" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Pixel Aligning</title>
		<link>http://likethought.com/lockfocus/2009/10/pixel-aligning/</link>
		<comments>http://likethought.com/lockfocus/2009/10/pixel-aligning/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 00:25:35 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/2009/10/pixel-aligning/</guid>
		<description><![CDATA[When you&#8217;re drawing graphics in your app, something that&#8217;s really important to make them look good is to pixel align them. This is the process of making sure all of the boundaries for a shape line up exactly with the screen&#8217;s pixel grid. 

The problem when you don&#8217;t pixel align your graphics is that when [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re drawing graphics in your app, something that&#8217;s really important to make them look good is to pixel align them. This is the process of making sure all of the boundaries for a shape line up exactly with the screen&#8217;s pixel grid. </p>
<p><span id="more-46"></span></p>
<p>The problem when you don&#8217;t pixel align your graphics is that when they end up between pixels, they get all blurry like this:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/withoutPixelAligning.png" alt="Blurry"></p>
<p>(On the right is a zoomed in version of the same image.) With pixel aligning, the same drawing becomes:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/withPixelAligning.png" alt="Blurry"></p>
<p>Everything is beautiful again! Luckily, pixel aligning is easy to do. The main steps are: convert all of the relevant coordinates to the pixel grid, round them, then convert them back. There&#8217;s one little things to keep in mind while doing this- when you stroke (outline) something instead of filling it, the geometry works a bit differently. Here&#8217;s what a pixel aligned rectangle fill should look like on a pixel grid:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/fillPixelAligned.png" alt="Filled"></p>
<p>Note that the coordinates of the rectangle (shown in red) line up with the pixel grid points (which are integer pixel values). On the other hand, a pixel aligned rectangle stroke looks like this:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/stroke1xPixelAligned.png" alt="Stroked"></p>
<p>Now, the rectangle&#8217;s coordinates end up in between the pixels! In fact, they should be at the centers of the pixels (integer and a half values). And in case you weren&#8217;t already confused, here&#8217;s a rectangle with a two pixel stroke:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/stroke2xPixelAligned.png" alt="Two Pixel Stroked"></p>
<p>Now the coordinates are back to integer values again. Luckily, this is pretty easy to generalize: <strong>odd stroke sizes</strong> should be rounded to <strong>integer and a half</strong> pixel values and <strong>even stroke sizes</strong> (including a fill, which is a zero size stroke) should be rounded to <strong>integer</strong> pixel values. What about decimal stroke values that are neither even or odd? Well there&#8217;s not much you can do to pixel align in that case since the stroke itself being a non-integer pixel size is already un-pixel-align-able. </p>
<p>Here&#8217;s some code to help you make all your drawing nice and pixel aligned:</p>
<p class="download"><a href="http://code.google.com/p/thoughtkit/source/browse/#svn/trunk/LTPixelAlign">View LTPixelAlign code</a></p>
<p><code>LTPixelAlign</code> is an <code>NSView</code> category that adds methods to pixel align <code>NSRect</code>&#8217;s, <code>NSPoint</code>&#8217;s, and stroke widths. The idea is that you can call these from your <code>NSView</code>&#8217;s <code>drawWithRect:</code> method to properly align the coordinates you use for drawing. Naturally these calls are resolution independence friendly- they rely on the view converting coordinates to pixels (with <code>convertRectToBase:</code> and friends) which takes the current resolution into account. At 1x, 1.25x, and 1.5x UI Resolutions, the non-aligned and pixel-aligned drawing shown above looks like:</p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/withPixelAligning1x.png" alt="Pixel Aligned at 1x"></p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/withPixelAligning1p25x.png" alt="Pixel Aligned at 1.25x"></p>
<p class="center"><img src="http://likethought.com/lockfocus/images/posts/withPixelAligning1p5x.png" alt="Pixel Aligned at 1.5x"></p>
<p>If you&#8217;re using any additional geometry transforms (like <code>NSAffineTransform</code>) while drawing, you&#8217;ll have to take those into account when pixel aligning. For scaling and translating, you should transform the coordinates, then pixel align them, then un-transform the results. For rotations and shears, you&#8217;re usually better off just not pixel aligning, since there&#8217;s no way to make your transformed graphics line up with the pixel grid. </p>
<p>Of course if this sounds too complicated, you can always just use Opacity&#8217;s source code exporting, which does all this for you&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2009/10/pixel-aligning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Another Way to Mimic the Artwork Column in Cocoa</title>
		<link>http://likethought.com/lockfocus/2009/10/another-way-to-mimic-the-artwork-column-in-cocoa/</link>
		<comments>http://likethought.com/lockfocus/2009/10/another-way-to-mimic-the-artwork-column-in-cocoa/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 21:49:43 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=26</guid>
		<description><![CDATA[Jesper&#8217;s recent post about mimicking the iTunes Artwork Column in Cocoa piqued my interest. It seemed like it should be possible to do this just within the confines of an NSTableView. 

After some thought, the solution I came up with was just drawing the contents that you wanted to appear in slices the height of [...]]]></description>
			<content:encoded><![CDATA[<p>Jesper&#8217;s <a href="http://waffle.wootest.net/2009/10/04/artwork-column-in-cocoa/">recent post</a> about mimicking the iTunes Artwork Column in Cocoa piqued my interest. It seemed like it should be possible to do this just within the confines of an NSTableView. </p>
<p><span id="more-26"></span></p>
<p>After some thought, the solution I came up with was just drawing the contents that you wanted to appear in slices the height of the rows in the proper column. If the cells are totally opaque (as they are in iTunes), then the cell&#8217;s normal contents (including row selection) won&#8217;t show through. I put together a basic example of this:</p>
<p class="download"><a href="http://downloads.likethought.com/code/ArtworkColumn.zip">Download ArtworkColumn code</a></p>
<p><img src="http://likethought.com/lockfocus/images/posts/ArtworkColumn.png" alt="ArtworkColumn"></p>
<p>ArtworkColumn is a simple proof of concept to show how such a thing could be done. Things would get complicated if your content was more than just an image on a background, but in that case you could probably cache the content as an image and draw that cached images in slices in a similar way.</p>
<p><strong>Update:</strong> Paul Kim has a <a href="http://www.noodlesoft.com/blog/2009/10/20/yet-another-way-to-mimic-the-artwork-column-in-cocoa/">much improved generalized version</a> of this approach on his <a href="http://www.noodlesoft.com/blog/">blog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2009/10/another-way-to-mimic-the-artwork-column-in-cocoa/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fun with Compositing Operations</title>
		<link>http://likethought.com/lockfocus/2009/04/fun-with-compositing-operations/</link>
		<comments>http://likethought.com/lockfocus/2009/04/fun-with-compositing-operations/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 16:45:11 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/2009/04/fun-with-compositing-operations/</guid>
		<description><![CDATA[Graphics in Cocoa have a powerful but rarely used feature: compositing operations. These are similar to blend modes in the PDF format and in many graphics editing programs. They let you easily do some interesting things&#8230;

What are They?
Compositing operations determine how a graphic is drawn on top of existing graphics. They essentially determine what equation [...]]]></description>
			<content:encoded><![CDATA[<p>Graphics in Cocoa have a powerful but rarely used feature: compositing operations. These are similar to blend modes in the PDF format and in many graphics editing programs. They let you easily do some interesting things&#8230;</p>
<p><span id="more-25"></span></p>
<h3>What are They?</h3>
<p>Compositing operations determine how a graphic is drawn on top of existing graphics. They essentially determine what equation is used to determine the resulting color of the draw operation. These operations are often called Porter-Duff compositing after the programmers who defined them. In Cocoa, they&#8217;re represented by the <code><a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/NSImage_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSCompositingOperation">NSCompositingOperation</a></code> enumeration and their counterpart in Quartz is <code><a href="http://developer.apple.com/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/doc/c_ref/CGBlendMode">CGBlendMode</a></code>. <code>CGBlendMode</code> was originally just for PDF blend modes, but in 10.5, the compositing operations were added. Note, though, that these new blend modes are <strong>not</strong> guaranteed to work with PDF <code>CGContextRef</code>&#8217;s, only bitmap ones.</p>
<h3>Where They&#8217;re Used</h3>
<p>NSCompositingOperation is used in several places in AppKit. Most prominently, you can set the <code>compositingOperation</code> for an <code>NSGraphicsContext</code> to determine the operation for subsequent drawing. <code>NSImage</code> also uses <code>NSCompositingOperation</code> in most of its drawing methods. Finally, <code>NSCompositingOperation</code> is used in several graphics related AppKit functions like <code>NSRectFillUsingOperation</code>, and in fact this is related to a common Cocoa graphics problem. <code>NSRectFill</code> and <code>NSFrameRect</code> both use the <code>NSCompositeCopy</code> operation, which is <strong>not</strong> the right operation to use when drawing with a partially transparent color. In that case, when the color gets drawn it will me partially black instead of partially transparent. To make sure your rects get drawn right with partial transparency, use <code>NSRectFillUsingOperation</code> and <code>NSFrameRectWithWidthUsingOperation</code> and specify <code>NSCompositeSourceOver</code> (which is generally what you use for &#8220;normal&#8221; drawing) for the compositing operation.</p>
<h3>Highlighting</h3>
<p>One convenient use for composite operations is to replicate the type of effect used by the Finder when you select an icon. This is essentially just darkening the icon, but not the background behind the icon. The operation to do this is <code>NSCompositeSourceAtop</code>, and here&#8217;s some example NSView drawing code:</p>
<pre>
- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];

   // Draw the image
   NSImage *image = [NSImage imageNamed:@"Opacity"];
   [image drawInRect:bounds fromRect:NSZeroRect
           operation:NSCompositeSourceOver fraction:1.0];

   // Draw the highlight
   [[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] setFill];
   NSRectFillUsingOperation(bounds, NSCompositeSourceAtop);
}
</pre>
<p>And here&#8217;s the resulting output:</p>
<p><img src="http://likethought.com/lockfocus/images/posts/badHighlight.png" alt="Bad Highlighting"></p>
<p>That&#8217;s not right! The problem here is that the NSView&#8217;s drawing is getting drawn together with the existing content (the window background). We need to isolate our drawing from what&#8217;s already there. A good way to do this is with a transparency layer, available from Quartz:</p>
<pre>
- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];

   // Start a transparency layer
   CGContextRef context = [[NSGraphicsContext currentContext]
                           graphicsPort];
   CGContextBeginTransparencyLayerWithRect(context,
                                           NSRectToCGRect(bounds),
                                           NULL);

   // Draw the image
   NSImage *image = [NSImage imageNamed:@"Opacity"];
   [image drawInRect:bounds fromRect:NSZeroRect
           operation:NSCompositeSourceOver fraction:1.0];

   // Draw the highlight
   [[NSColor colorWithCalibratedWhite:0.0 alpha:0.5] setFill];
   NSRectFillUsingOperation(bounds, NSCompositeSourceAtop);

   // End the transparency layer
   CGContextEndTransparencyLayer(context);
}
</pre>
<p>And now the image highlights correctly:</p>
<p><img src="http://likethought.com/lockfocus/images/posts/goodHighlight.png" alt="Good Highlighting"></p>
<h3>Coloring Images</h3>
<p>Another nice trick you can do with the <code>NSCompositeSourceAtop</code> operation is re-coloring an image or graphic. This is a similar idea to highlighting, but goes further and completely replaces all of the (non-transparent) colors in the image, treating it sort of like a mask. I&#8217;ve found this useful for things like drawing images in table rows that should highlight in white when selected. I&#8217;ve put together a special function to do this coloring for you (including setting up a transparency layer to prevent coloring the background):</p>
<p class="download"><a href="http://code.google.com/p/thoughtkit/source/browse/#svn/trunk/LTColoredDrawing">View LTColoredDrawing code</a></p>
<p>Here&#8217;s an example of how to use LTColoredDrawing in an NSView:</p>
<pre>
- (void)drawRect:(NSRect)rect
{
   NSRect bounds = [self bounds];

   // Start coloring
   NSColor *color = [NSColor blueColor];
   [color beginDrawingColoredInRect:bounds];

   // Draw the image
   NSImage *image = [NSImage imageNamed:@"Opacity"];
   [image drawInRect:bounds fromRect:NSZeroRect
           operation:NSCompositeSourceOver fraction:1.0];

   // Finish coloring
   [color endDrawingColoredInRect:bounds];
}
</pre>
<p>And here&#8217;s what this looks like in action:</p>
<p><img src="http://likethought.com/lockfocus/images/posts/blueOpacity.png" alt="Colored Opacity"></p>
<h3>Find Out More</h3>
<p>You can explore compositing modes more with Opacity. Create an image with 2 or more layers, then select the top layer. Select the Window > Show Layers Info menu item and look at the Blend popup. The top two sections are PDF blend modes, and the bottom section includes the compositing modes. See what kinds of effects you can come up with!</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2009/04/fun-with-compositing-operations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Compiling Opacity Images</title>
		<link>http://likethought.com/lockfocus/2008/05/compiling-opacity-images/</link>
		<comments>http://likethought.com/lockfocus/2008/05/compiling-opacity-images/#comments</comments>
		<pubDate>Thu, 29 May 2008 12:16:47 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=17</guid>
		<description><![CDATA[Opacity is great for creating graphics for use in applications, but how do you ship those images with the application? Including the .opacity file itself would be bad (that would be like shipping your source code with the application), a native image format like TIFF would be better. At the same time, though, it&#8217;d be [...]]]></description>
			<content:encoded><![CDATA[<p>Opacity is great for creating graphics for use in applications, but how do you ship those images with the application? Including the .opacity file itself would be bad (that would be like shipping your source code with the application), a native image format like TIFF would be better. At the same time, though, it&#8217;d be nice to be able to directly edit a .opacity source file and not have to manually rebuild the associated .tiff file each time. Luckily there&#8217;s an easy way to make this happen automatically with Opacity.</p>
<p><span id="more-17"></span></p>
<p>Opacity includes opacityutil, a command line utility that can convert images between the formats supported by Opacity. You can use this functionality in Xcode to create a Build Rule that will dynamically convert .opacity images in your project to TIFF files (or any other supported format) at compile time. </p>
<p>To do this, first open your application&#8217;s project in Xcode. Add any .opacity images you want to the project (and include them in the appropriate target). Then, double click the application&#8217;s target to edit it. Select the Rules tab and click the plus button to add a Build Rule. Change the &#8220;Process:&#8221; popup to &#8220;Source files with names matching:&#8221; and enter *.opacity in the field (to match all .opacity files). Then change the &#8220;using:&#8221; popup to &#8220;Custom script:&#8221; and enter the following script (which should be all on one line):</p>
<pre>opacityutil -save -out
  ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.tiff ${INPUT_FILE_PATH}</pre>
<p>Finally, add an output file (by clicking the plus button). Change this output file to:</p>
<pre>$(DERIVED_FILES_DIR)/$(INPUT_FILE_BASE).tiff</pre>
<p>The result should look something like this:</p>
<p><img src="http://www.likethought.com/myriad/images/posts/buildRule.png" alt="Build Rule" /></p>
<p>With this setup, all .opacity files included in the target will get converted into TIFF images that will be added to the application. You can change the format for the built images by changing the two .tiff extensions above to an extension for another supported format, like .png for PNG images.</p>
<p>Opacity&#8217;s Xcode support was inspired by <a href="http://boredzo.org/blog/archives/2006-12-06/compiling-eps-files-to-pdf-files-using-xcode">this post</a> by <a href="http://boredzo.org/">Peter Hosey</a>.</p>
<p>Of course if you don&#8217;t use Xcode, you can also manually build your .opacity image to a different format with Factories in Opacity.</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2008/05/compiling-opacity-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why Opacity?</title>
		<link>http://likethought.com/lockfocus/2008/05/why-opacity/</link>
		<comments>http://likethought.com/lockfocus/2008/05/why-opacity/#comments</comments>
		<pubDate>Thu, 15 May 2008 02:10:05 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=15</guid>
		<description><![CDATA[I few months ago I released Opacity, a new graphics editor. With all of the other graphics editors available on Mac OS X, I want to write a little about why I thought it was necessary to create Opacity. 

Design
While working on my first program (Lexicon), I needed many graphics. Creating all of these, from [...]]]></description>
			<content:encoded><![CDATA[<p>I few months ago I released <a href="http://likethought.com/opacity/">Opacity</a>, a new graphics editor. With all of the other graphics editors available on Mac OS X, I want to write a little about why I thought it was necessary to create Opacity. </p>
<p><span id="more-15"></span></p>
<h3>Design</h3>
<p>While working on my first program (Lexicon), I needed many graphics. Creating all of these, from icons to toolbar images, was a pain. At the time, Photoshop and Illustrator were the main tools for graphic editing, but they&#8217;re essentially jack of all trade editors. These programs are good for everything from photo editing to print graphics but aren&#8217;t designed specifically for editing screen graphics. It seemed to me that an application focused on just making screen graphics could do a much better job for users when they&#8217;re not editing photos or print graphics. </p>
<p>This made my goal for Opacity clear: Create a graphics editor for the screen, optimized for making images for icons, applications and the web.</p>
<h3>Workflow</h3>
<p>The part of creating screen images that I thought was the most painful was the workflow, so I focused a lot of attention to how to improve it. Before Opacity, the steps to create an application icon (for example), were as follows: </p>
<ul>
<li>Create a vector graphic in a vector editor (like Illustrator)</li>
<li>Import and rasterize the vector graphic with a pixel editor (like Photoshop)</li>
<li>Export the image at the necessary resolutions</li>
<li>Mess around with differences in things like premultiplied colors and color spaces</li>
<li>Use Icon Composer to piece the images back together and save as a .icns file</li>
<li>Put the .icns file into an application to see how it will actually look</li>
</ul>
<p>This workflow is already no picnic, but as you&#8217;re editing an icon you have to repeat this every time you make changes! For application and web graphics, you have to go through similar but slightly different workflows (see <a href="http://likethought.com/opacity/workflow/">here</a> for details). So not only do you need to buy and learn all of these different applications, you also have to learn all of the different workflows. </p>
<p>In Opacity, these steps and workflows are all unified into one application. You can design your graphics with vectors and see them at any different resolutions you want. And, of course, Opacity natively supports all of the formats you would need for the screen (including SVG as of Opacity 1.1). </p>
<p>Opacity also uses Factories to improve your workflow. A factory exports your image to a specified format and path. This removes all of the repetitive &#8220;Save As&#8221; or &#8220;Export&#8221; steps you&#8217;d normally have to go through, in addition to saving the export settings you&#8217;ve specified. </p>
<h3>The Future</h3>
<p>Since I started Opacity, there&#8217;ve been several new graphics editors released, but they all seem to follow Photoshop&#8217;s Swiss Army knife approach. When I designed Opacity, I focused on what the user wanted to do, instead of on using specific technologies. I think this approach works out well for users, in Opacity and in other programs like Aperture and Lightroom. I hope to see more new applications for the Mac that are designed this way in the future.</p>
<p>As resolution independence approaches, there&#8217;ll be even more need for a dedicated screen graphics editor like Opacity. I also have many features I plan to add to make it even easier for designers to make and implement great looking images. </p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2008/05/why-opacity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drawing Between the Lines</title>
		<link>http://likethought.com/lockfocus/2008/04/drawing-between-the-lines/</link>
		<comments>http://likethought.com/lockfocus/2008/04/drawing-between-the-lines/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 00:34:57 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=13</guid>
		<description><![CDATA[Mac OS X has a wealth of graphics frameworks. From the PDF-based Quartz to AppKit to the filter-based Core Image, there&#8217;s something for everybody. Unfortunately, these frameworks each do things a little differently, which can lead to trouble when getting them to work with each other. There are system-provided ways to convert between some of [...]]]></description>
			<content:encoded><![CDATA[<p>Mac OS X has a wealth of graphics frameworks. From the PDF-based Quartz to AppKit to the filter-based Core Image, there&#8217;s something for everybody. Unfortunately, these frameworks each do things a little differently, which can lead to trouble when getting them to work with each other. There are system-provided ways to convert between some of these different types, but not for others. I put together a few categories with methods to make it easier for these frameworks to all get along. </p>
<p><span id="more-13"></span></p>
<p class="download"><a href="http://code.google.com/p/thoughtkit/source/browse/#svn/trunk/LTConversions">View LTConversions code</a></p>
<h3>Geometry</h3>
<p>One of the most common mis-matching issues developers run into is the different geometry types in Quartz and Cocoa. Quartz has <code>CGRect</code>, <code>CGPoint</code> and <code>CGSize</code> while Cocoa uses <code>NSRect</code>, <code>NSPoint</code> and <code>NSSize</code>. They have all of the same attributes but are still different. </p>
<p>Luckily this situation is much improved in Leopard with a whole host of conversion functions like <code>NSRectFromCGRect()</code>. Even better, in 64 bit Cocoa all of the <code>NS*</code> types are <code>typedef</code>&#8216;ed as their <code>CG*</code> equivalents! This is a great improvement, and even if you&#8217;re not 64 bit only, you can define <code>NS_BUILD_32_LIKE_64</code> to still use the 64 bit versions of the <code>NS*</code> structures.</p>
<p>Core Image, though, uses yet another representation of geometric values. The <code>CIVector</code> class is used for rectangles, points, sizes and even 3D points. <code>LTConversions</code> includes methods to convert Quartz and Cocoa geometric values to and from their <code>CIVector</code> equivalents. </p>
<h3>Color Spaces</h3>
<p>Color Spaces are used to specify how to interpret the values in a color. Quartz uses <code>CGColorSpaceRef</code> and Cocoa uses <code>NSColorSpace</code>. <code>NSColorSpace</code> is great for converting color spaces-it can convert to and from <code>CMProfileRef</code> (used by ColorSync) and from ICC profiles (.icc files created with ColorSync Utility). New in Leopard, it can also convert to and from <code>CGColorSpaceRef</code>. Core Image does not have its own color space object, so in Leopard <code>NSColorSpace</code> can convert between pretty much any color space format you might need. </p>
<h3>Colors</h3>
<p>For colors, there three very similar flavors. <code>NSColor</code>, <code>CGColorRef</code> and <code>CIColor</code> are pretty much the same idea, and with <code>LTConversions</code> you can easily convert between them. Note that it doesn&#8217;t handle pattern color conversion since they&#8217;re treated a little differently in Quartz and AppKit (and don&#8217;t really exist in Core Image).</p>
<h3>Paths</h3>
<p>The situation with paths is a little strange. Quartz&#8217;s <code>CGPathRef</code> actually has (a little) more functionality than AppKit&#8217;s <code>NSBezierPath</code>. <code>CGPathRef</code> has cubic and quadratic Bézier curves, while <code>NSBezierPath</code> only has cubic curves. It&#8217;s not a major omission, but it seems strange that <code>NSBezierPath</code> is missing this, making it not quite a perfect mirror of <code>CGPathRef</code>. <code>LTConversions</code> has a method to convert a <code>NSBezierPath</code> to a <code>CGPathRef</code>, but not the other way. </p>
<h3>Images</h3>
<p>There&#8217;s also a host of image types. <code>CGImageRef</code> and <code>CIImage</code> don&#8217;t share <code>NSImage</code>&#8217;s concept of representations (which use the <code>NSImageRep</code> class), but otherwise they are very similar. <code>LTConversions</code> has methods for converting between these image types, but if you&#8217;re doing anything fancy with multiple image representations, you should probably do the conversion yourself. </p>
<h3>Wrap Up</h3>
<p>Leopard is required because of some of the new Color and Image conversions, and everything should work with (or without) Garbage Collection and in 64 bit. Leopard&#8217;s Core Animation doesn&#8217;t add any of its own new basic types, and generally uses those from Quartz (so using Core Animation together with Cocoa requires a lot of conversions). Of course, on a (purely hypothetical) platform that had Quartz but no AppKit or Core Image, most of these conversions would be unnecessary&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2008/04/drawing-between-the-lines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A (Slightly) Improved NSTableView</title>
		<link>http://likethought.com/lockfocus/2008/04/a-slightly-improved-nstableview/</link>
		<comments>http://likethought.com/lockfocus/2008/04/a-slightly-improved-nstableview/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 23:09:40 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=19</guid>
		<description><![CDATA[While working on Lexicon and Opacity, I&#8217;ve used NSTableViews a lot. They work very well, but there are a few convenient behaviors that they don&#8217;t have out of the box. 

Some of the features that were missing in Tiger were type to select, source list appearance, and tooltips to show the text of a cell [...]]]></description>
			<content:encoded><![CDATA[<p>While working on Lexicon and Opacity, I&#8217;ve used NSTableViews a lot. They work very well, but there are a few convenient behaviors that they don&#8217;t have out of the box. </p>
<p><span id="more-19"></span></p>
<p>Some of the features that were missing in Tiger were type to select, source list appearance, and tooltips to show the text of a cell when it&#8217;s clipped. I implemented these and other behaviors for Lexicon, only to have them built in to NSTableView in Leopard! (not that I&#8217;m bitter) Check the AppKit release notes for all of the details on what&#8217;s new in NSTableView.</p>
<p>For Opacity, I put together a subclass of NSTableView that adds a few more features-specifically for handling keyboard presses. LTKeyPressTableView adds enter or return to edit a row, delete to delete the current row, and hooks to intercept left and right key presses. </p>
<p class="download"><a href="http://code.google.com/p/thoughtkit/source/browse/#svn/trunk/LTKeyPressTableView">View LTKeyPressTableView code</a></p>
<p>LTKeyPressTableView uses the table view&#8217;s existing delegate, adding a few optional delegate methods. Implement <code>deleteSelectionFromTableView:</code> to do something when the user presses delete with a row (or rows) selected, and <code>goLeftFromTableView:</code> or <code>goRightFromTableView:</code> for when they press the corresponding arrow keys. Enter automatically starts editing the first editable column of the table (if there is one) unless you implement <code>preventEnterEditingTableView:</code> to return <code>YES</code>. (<strong>Note:</strong> LTKeyPressTableView requires Leopard.)</p>
<p>By using LTKeyPressTableView for your tables, you can easily add user-friendly behavior with just a few delegate methods. As an added bonus, a key-press version of NSOutlineView is also included. Try them out!</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2008/04/a-slightly-improved-nstableview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic Sparkle Release Notes</title>
		<link>http://likethought.com/lockfocus/2006/05/dynamic-sparkle-release-notes/</link>
		<comments>http://likethought.com/lockfocus/2006/05/dynamic-sparkle-release-notes/#comments</comments>
		<pubDate>Tue, 30 May 2006 03:59:00 +0000</pubDate>
		<dc:creator>Jacob</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://likethought.com/lockfocus/?p=9</guid>
		<description><![CDATA[By now I’m sure all Mac OS X developers have heard of Sparkle &#8211; the excellent auto-updating framework by Andy Matuschak. When I added Sparkle to Lexicon, I only ran into one problem. The release notes that Sparkle displays are decided by what version you are updating to, but they should depend only on what [...]]]></description>
			<content:encoded><![CDATA[<p>By now I’m sure all Mac OS X developers have heard of Sparkle &#8211; the excellent auto-updating framework by Andy Matuschak. When I added Sparkle to Lexicon, I only ran into one problem. The release notes that Sparkle displays are decided by what version you are updating to, but they should depend only on what version you are updating from.</p>
<p><span id="more-9"></span></p>
<p>This might sound a little backwards at first, but let me explain. In the most common updating circumstances, you want all of your customers on the latest version. Here&#8217;s an example: You first release your 1.0, and later release 1.1 to with a killer new feature-everyone updating should see the 1.1 release notes, which mention the new feature. Then later you release 1.2, which has some bug fixes. Now you’ll want everyone to update to 1.2, so you don&#8217;t want to show just the 1.1 changes by themselves. But, what about the people who are still running 1.0? You want them to see the changes and features in 1.1 in addition to those from 1.2. If we know what version they&#8217;re updating from, we can figure out which release notes to show (always going up to the latest release).</p>
<p>So I made a minor change to Sparkle to address this. In the checkForUpdatesAndNotify: method in SUUpdater.m, I added the line in bold:</p>
<pre>
// ... code to get appcastString from user defaults or Info.plist
SUAppcast *appcast = [[SUAppcast alloc] init];
[appcast setDelegate:self];
<strong>appcastString = [NSString stringWithFormat:appcastString,
    SUHostAppVersion()];</strong>
[appcast fetchAppcastFromURL:[NSURL URLWithString:appcastString]];
</pre>
<p>Now instead of getting a request for something like:</p>
<pre>http://downloads.likethought.com/appcasts/lexicon.rss</pre>
<p>I get a request for:</p>
<pre>http://downloads.likethought.com/appcasts/lexicon.php?version=1.0</pre>
<p>In this appcast file, you can specify a URL for the change notes. I send them all to the same PHP file (since they will all be updating to whatever the latest version is), and I pass this PHP file the $version variable. This is what my changes PHP file looks like:</p>
<pre>
&lt;html&gt;
    &lt;body&gt;
    &lt;?php
        $versionNum = ereg_replace(&quot;[^[:digit:]]&quot;,&quot;&quot;,$version);
        while(strlen($versionNum) &lt; 3) {
            $versionNum = $versionNum . &quot;0&quot;;
        }
        if ($versionNum &lt; 110) {
            echo &quot;&lt;h2&gt;Changes in 1.1&lt;/h2&gt;&lt;ul&gt;&quot;;
            echo &quot;&lt;li&gt;Added killer new feature&lt;/li&gt;&quot;;
            echo &quot;&lt;/ul&gt;&quot;;
        }
        if ($versionNum &lt; 120) {
            echo &quot;&lt;h2&gt;Changes in 1.2&lt;/h2&gt;&lt;ul&gt;&quot;;
            echo &quot;&lt;li&gt;Bug Fixes&lt;/li&gt;&quot;;
            echo &quot;&lt;/ul&gt;&quot;;
        }
    ?&gt;
    &lt;/body&gt;
&lt;/html&gt;
</pre>
<p>I only do very basic processing, strip out non-numeric text and convert the version to an integer, then check which changes they need to see. If you want to implement something similar, you could check for more differences in the version (like 1.0, 1.0b, 1.0rc-final, etc) or you could only prompt users to update to the same major version that they are running (i.e. not from 1.x to 2.x). The most important change is just the line in bold added to the Sparkle code. With that added, you can tweak to your heart’s desire.</p>
]]></content:encoded>
			<wfw:commentRss>http://likethought.com/lockfocus/2006/05/dynamic-sparkle-release-notes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
