[Drawkit] DrawKit b6 now available

Rudy Richter rudy at AmbrosiaSW.com
Mon Jul 27 15:16:34 PDT 2009


Has any work been done to ready DrawKit for the 64bit transition and  
have had a chance to setup the public source repository yet?

-rudy

On Jul 14, 2009, at 10:47 PM, Graham Cox wrote:

> Finally, I got around to updating the site with the latest source.
>
> http://apptree.net/drawkitmain.htm
>
> Note that this version has quite a large number of changes (due to  
> the long time between updates - sorry about that) but by and large  
> should require very few changes to your client code. Do let me know  
> if you have any problems either with the downloads or with building.
>
> Particular areas that you'll need to test are text and object  
> metadata - they are the parts that have changed most significantly.
>
> The release notes are copied below.
>
> --Graham
>
> Release 1.0 beta 6
> July 15th, 2009
>
> 1. Objects that can be passed to a renderer must now implement the  
> DKRenderable formal protocol. DKDrawableObject does, so no change is  
> required. However it allows other kinds of objects to be passed to a  
> style/renderer for special purposes if necessary while reducing the  
> likelihood of introducing bugs by doing so. The previous informal  
> protocol for this purpose is deprecated. The protocol is defined in  
> DKRasterizerProtocol.h
>
> 2. Style scripting support, which has been deprecated for several  
> releases now, has gone.
>
> 3. Additional objects storage class, DKBSPDirectObjectStorage,  
> added. This uses a similar algorithm to DKBSPObjectStorage, but  
> instead of indexing it stores the objects directly. This seems to  
> yield significant speed advantages, though more profiling is needed  
> to quantify this. The storage itself is not archived as part of the  
> drawing - only its objects are, and the currently set preferred  
> class for the storage is honoured on dearchiving. Files saved with  
> Beta 5 did archive the storage and they will be automatically  
> converted when read. Re-saving the file will update to the newer  
> approach.
>
> 4. Code that draws and iterates over drawables is gradually being  
> updated to take advantage of the benefits of the storage model. In  
> most cases this means that fewer objects need to be iterated over  
> for many operations, yielding noticable performance benefits. In  
> addition, time-critical code that uses NSEnumerator is replaced by  
> the much faster CFArrayApplyFunction methodology. This works on 10.4  
> and earlier, unlike ObjC-2.0 fast enumeration. Upshot: Teh Snappy™.  
> Maybe.
>
> 5. Locked layers are no longer auto-activated by default. This  
> reflects the typical usage patterns for locked layers as background  
> content or for tracing.
>
> 6. DKLayerGroup now correctly propagates hit-testing recursively  
> down through a layer hierarchy.
>
> 7. Select/Edit tool now implements an alternative dragging  
> methodology in an effort to boost performance substantially when  
> dragging a large number of objects at once. This method uses a  
> single drag image as a proxy for the objects being dragged, then  
> repositions the real objects on mouse up. This approach can be  
> turned off (thus using the old method), turned on for all objects or  
> used when a certain threshold object count is exceeded. This is done  
> by calling [DKSelectAndEditTool setDragProxyThreshold:] with values  
> of 0, 1 and the required threshold respectively. The default in this  
> release is to use the alternative method for 50 or more objects. The  
> main downside of this approach is that the interleaving of the  
> dragged objects with non-dragged objects during the drag cannot be  
> preserved. The Z-order is maintained and restored at the end of the  
> drag. In practice the performance benefit will probably outweigh  
> this minor inconvenience. Currently the drag image will noticeably  
> pixellate at higher zooms also.
>
> 8. Select/Edit tool now treats locked objects slightly differently.  
> A drag that starts in a locked object selects it as usual, but now  
> continues in the selection rect dragging mode. This gives more  
> useful behaviour: objects overlaid on some locked background object  
> can now be drag-selected as normal even if the drag started in the  
> background object.
>
> 9. DKLayerGroup and DKViewController add methods to permit the  
> implementation of a "Hide Others" and "Show All" command for  
> operating on layers if desired.
>
> 10. Added some additional properties to DKHatching: line roughness  
> and "wobblyness" which together can be used to create some  
> additional effects.
>
> 11. Bugfix: objects resulting from combinatorial operations now  
> preserve any attached user data from the source object.
>
> 12. Metadata keys in both DKLayer and DKDrawableObject are now case- 
> insensitive. Existing files will have their keys converted if  
> necessary, at the possible risk of data loss if you have keys that  
> differ only in case. The case insensitivity is achieved by always  
> converting all key strings to lowercase. If you set a key in the  
> user info dictionary directly, rather than using the metadata  
> methods, you need to ensure this otherwise your data won't be  
> findable.
>
> 13. Drawable Objects now support the concept of ghosting, which  
> draws the object using a light grey thin outline rather than its  
> attached style. Otherwise the object behaves as a normal visible  
> object. Ghosting is a good alternative to hiding objects in many  
> applications. DKObjectDrawingLayer supports high-level commands for  
> ghosting and unghosting items in the selection. Some renderers, such  
> as DKTextAdornment, are ghosting aware, though most don't need to be  
> as ghosting typically bypasses the style altogether. The grey  
> ghosting colour is settable as a global preference using + 
> [DKDrawableObject setGhostColour:]; You can also override an  
> object's -drawGhostedContent method to customise the ghosted  
> appearance.
>
> 14. Bugfix:  Layer Bring Forward/Bring To Front/Send Backward/Send  
> To Back commands now operate without ambiguity within their  
> immediate containing group only (which for the case of a flat layer  
> list is the drawing, as before). The earlier implementation was  
> buggy when additional layer groups were present.
>
> 15. Intersection operation now preserves the style and metadata from  
> the lower object rather than the upper. This better reflects real- 
> world usage of this operation to extract a shape from a larger one  
> using an overlaid "cookie cutter".
>
> 16. Bugfix: -hexString in NSColor category makes a more accurate job  
> of rounding the colour component values when determining the hex  
> value. This prevents light greys for example incorrectly coming out  
> as white.
>
> 17. "Break Apart" operation now available for shapes without  
> converting to a path first. Metadata is preserved as is the true  
> class of the object.
>
> 18. DKTextShape and DKTextPath modified in behaviour such that  
> deliberate changes to the text made by the user "stick" properly  
> when saving the file. The change involves mutating the existing  
> style, if it's a registered style, into an identical one but lacking  
> text attributes. This allows the text to be set both by the user  
> directly, and also by applying a style having text attributes, but  
> without any user-made changes getting reverted when a file  
> containing such objects is reloaded. A memory leak and a KVO error  
> bug was also fixed in the DKTextShape object.
>
> 19. Text on a path now lays out the full attributed string exactly  
> as it would be drawn by the standard text system, so it is possible  
> to vary attributes such as font, underlining, superscripting, colour  
> and shadow within the string.
>
> 20. DKDrawableObject now supports a global table used to map classes  
> when performing interconversions from one type of object to another  
> (e.g. path -> shape). By customising this table, your app can  
> substitute a subclass to be used when performing an interconversion  
> that normally would make an object of the base class. All  
> conversions done by DK now go through this table, but by default no  
> substitution is performed (and in fact the table is nil).
>
> 21. The NSBezierPath+Geometry category has been split into a new  
> category NSBezierPath+Text which contains all the text-on-path and  
> text-wrap-in-shape methods.
>
> 22. DKTextPath now has a contextual menu that mirrors the one used  
> by DKTextShape. Both have been cleaned up.
>
> 23. DKDrawablePath creation allows modal creation loops to be  
> interrupted (ended) by hitting any key on the keyboard as well as  
> the previously supported methods. This makes it easier to "get out  
> of" a modal loop if you were not expecting to be in one. Also some  
> additional feedback via the floating info window was added for  
> several of the path loops that previously didn't have anything.
>
> 24. Text on a path now supports underline and strikethrough  
> attributes. Currently these are based on the metrics returned by  
> NSFont and some tweaking - the positioning differs very slightly  
> from text laid out by the system and the discrepancy varies with the  
> font. It's unclear why the system is not using the metrics it is  
> given. Currently, the NSUnderlineByWordMask flag is not supported.
>
> 25. Text on a path now renders any text shadow the same way that  
> NSTextView etc do. This is to give consistency beyween text blocks  
> laid out by the system and text on paths. However this way of  
> drawing shadows is a bit dumb - it changes according to the view  
> zoom scale. You can use the earlier behaviour for text on a path by  
> setting DK_TEXT_SHADOW_COMPATIBLE to 1 and recompiling. There's no  
> way to change how the system draws text shadows though.
>
> 26. Locked path objects no longer show the control knobs and bars  
> since they can't be moved anyway. On-path knobs are shown as before  
> using the locked style. This reduces visual clutter.
>
> 27. DKGuideLayer now manages its cursor to provide useful feedback  
> when dragging, deleting and placing. When creating a new guide by  
> dragging from a ruler, the guide layer is now made active which  
> brings its cursors into play. While dragging a guide, the up/down or  
> left/right curosr is shown. When not dragging, the open hand cursor  
> is shown. When a guide is dragged into the "delete" zone (the  
> margins, typically), the disappearing item cursor is shown and when  
> a guide is deleted the 'poof' animation is shown. If locked the  
> layer shows the arrow. Guide layers also now maintain the deletion  
> area independently of the drawing's interior. By default this is set  
> to be the same as the drawing's interior but you can set it to some  
> other rect if you want (the most likely alternative is the entire  
> drawing).
>
> 28. DKDrawing no longer calls DKStyleRegistry's loadDefaults from  
> its own loadDefaults. This was assuming too much about what an app's  
> needs are here. If you are relying on this, you need to call the  
> registry's loadDefaults yourself from the application delegate's - 
> applicationDidFinishLaunching: method. The same applies to the call  
> to the registry's saveDefaults.
>
> 29. Layers can get directly notified when they, or a group  
> containing them, was added to the root drawing. The intention is to  
> perform additional setup with knowledge of the drawing such as its  
> size. The method is -wasAddedToDrawing:
>
> 30. The persistence mechanism for DKDrawingTool made more general.  
> Instead of -saveDefaults assuming that we are interested in the  
> style, we leave it up to the tool object, using the new methods - 
> persistentData and -shouldLoadPersistentData: DKObjectCreationTool  
> now handles the style as before using this mechanism, but other tool  
> classes can do something different. The change is fully backward  
> compatible. In addition DKObjectCreationTool now correctly attempts  
> to remerge the style with the registry as it should to ensure that  
> two copies of the same style don't end up in the system (and then  
> transferred to drawings). While a bug that was leaking into saved  
> documents, it's self-correcting in that such documents will fix  
> themselves up when they do their own remerge on being opened.
>
> 31. Removed misguided attempt at caching point hit-testing on  
> drawables - led to problems with hit-testing reliability.
>
> 32. DKStroke drops the unimplemented properties pathScaleFactor and  
> strokePosition, but gains lateralOffset, which is a better and more  
> general solution (and one that is actually implemented).
>
> 33. DKDrawing now allows a delegate. Currently the only delegate  
> methods posible are to hook into before and after drawing the content.
>
> 34. Ruler visibility is now persistent - new instances of  
> DKDrawingView initially set the rulers according to the most recent  
> state seen. If never set, the default is now hidden, not shown.
>
> 35. [NSBezierPath bezierPathByInterpolatingPath:] is now functional.
>
> 36. GCZoomView now implements all of the scrollwheel control flags  
> as class methods, so they are applied to all instances in a given  
> application. This makes more sense and allows them to be easily  
> linked with user defaults. DKDrawingView defines some standard user  
> defaults keys for enabling and setting the sense of scroll wheel  
> operations. These are loaded as needed but never set - your app can  
> expose these settings in its preferences if it wants to.
>
> 37. Menu items for "Hide/Show Grid" and "Hide/Show Guides" now use  
> the actual set name of the layers in question, rather than assuming  
> "Grid" and "Guides".
>
> 38. Default layer cache settings for DKObjectOwnerLayer are now  
> settable. Saved cache settings are ignored. The default is no  
> caching. Note that in real-world testing, using a PDF-based cache  
> was found to be often slower than drawing the objects directly,  
> especially with partitioned storage. CGLayer cacheing is still  
> faster, but suffers from pixellation effects.
>
> 39. There is now a formal protocol - DKDrawableContainer - that  
> defines the methods a container must implement if it claims to "own"  
> or "contain" any drawable. Existing objects that were acting as  
> containers, namely DKObjectOwnerLayer and DKShapeGroup, now formally  
> adopt this protocol. There is no functional difference but the  
> formal protocol both ensures correctness for containers and makes  
> clear what methods a container needs to support.
>
> 40. Archiving of DKImageShape and interaction with image data  
> manager reworked to give a much more robust and straightforward  
> implementation. As before, wherever possible original image data is  
> stored in a document archive and used to recreate image shapes as  
> needed. Only one copy of the data is saved no matter how many image  
> shapes share it, keeping file sizes down, and since the images are  
> recreated from the original data when dearchived, quality is kept as  
> high as possible. The difference now is that the image shape also  
> retains a reference to the data and makes sure that this gets copied  
> to new image data managers as they are needed. It can also create  
> its own image even if no manager is available, and will update it  
> when the opportunity arises. The result is far less chance of an  
> image shape being unable to instantiate itself even when archived in  
> a non-standard way or from within a custom container. Note that  
> older archives will remain operational and will update to the  
> revised archive scheme if saved.
>
> 41. Hit-testing of very narrow or offset paths made much more  
> reliable using a temporary stroke attribute that isn't visible to  
> the user. Allows tools such as insert/remove path point to work even  
> on offset paths, or paths with very thin strokes that can be hard to  
> hit. Additionally, hatches are treated as 'solid' for the purpose of  
> hit-testing
>
> 42. New algorithm for generating the offset or parallel path, more  
> accurate, also allows for differing treatments of corners (mitre,  
> round or bevel). The use of paralleloidPathWithOffset2 now calls  
> this new code using the path's current line join style.
>
> 43. An enhancement to the message forwarding performed by  
> DKObjectDrawingLayer allows multiple selections to be handled  
> automatically where the actual action is implemented by the object,  
> rather than the layer. Previously, forwarding from the layer to an  
> object was only done if exactly one selected object could respond to  
> the message. This meant that any actions pertaining to a set of  
> selected objects had to be implemented strictly by the layer. For  
> certain operations, such as conversions, this was inconvenient, and  
> disallowed such operations t be performed on more than one object at  
> a time. Now this can be handled for multiple selected objects  
> automatically, even when the action is handled only by the object.  
> For backward compatibility, this feature is turned off by default,  
> and is not saved in an archive. It can be enabled using - 
> setMultipleSelectionAutoForwarding:YES. The layer will temporarily  
> buffer selection changes when invoking multiple commands in this way  
> such that the user will "see" the same selection behaviour as if the  
> message had been handled by the layer itself.
>
> 44. The DK project now includes a unit test target. Over time more  
> tests will be added; right now only a test for the BSP storage sub- 
> system is included. However, the test is fairly thorough and as a  
> result a couple of subtle bugs were found and corrected in the  
> tested classes.
>
> 45. DKDrawkitInspectorBase was changed so that it passes nil to - 
> redisplayContentForSelection: when the document resigned main.  
> Previously it passed the "current" selection but this is stale when  
> a document is closing.
>
> 46. The select/edit tool now posts a mouse up event if appropriate  
> when an object is dragged out of a drawing. This is necessary  
> because the normal drag handling swallows the mouse up, but without  
> one the tool controller can be left in an unbalanced state. This  
> fixes the issue of the undo manager going on strike following this  
> kind of drag.
>
> 47. DKShapeGroup can now optionally clip its contents to the group's  
> path. By default this is off, but easily enabled using a new  
> contextual menu item. When enabled, the selection highlight reveals  
> the path.
>
> 48. When interactively creating bezier paths and irregular polygons,  
> the delete key can now be used to "back up" by one element (in other  
> words, deleting the current point being positioned).
>
> 49. DKDrawingDocument factors the creation of a print drawing view  
> into an overridable method allowing easy customisation of the print  
> view.
>
> 50. DKStyleRegistry no longer enables style notifications by  
> default. A new method, +setStyleNotificationsEnabled:, allows you to  
> turn this on or off, but it's now up to your app to do this. It's  
> only needed if you're using the built-in menu handling, otherwise  
> leaving it off speeds up various operations. Also, DKCategoryManager  
> uses a different approach in -replaceContentsWithData: which greatly  
> improves its speed.
>
> 51. Double-click detection changed to be slightly earlier so that it  
> is invoked even when a handle or other partcode of an object is hit.  
> Previously it was only called when the "entire object" partcode was  
> hit, so looking for particular partcodes in the double-click method  
> didn't work.
>
> 52. A new vertical alignment constant for text-on-a-path  
> automatically centres the text on the path based on the cap height  
> of the font the text is drawn in. This visually centres the text on  
> the path rather than placing its baseline there. DKTextAdornment  
> implements this for text on path layouts which is therefore  
> inherited by DKTextPath and DKTextShape.
>
> 53. DKStyle has some additional class methods for pasteboard  
> operations: +canInitWithPasteboard: and +stylePasteboardTypes
>
> 54. DKRasterizers now broadcast notifications before and after every  
> property change, so that non-style clients can easily get notified  
> when any property of the reasterizer changes. This is used by  
> DKTextPath, DKTextShape for example, which uses an internal  
> adornment without a style.
>
> 55. DKTextADornment now uses a much more versatile method for  
> handling substitution of metadata values into the text stream. Now,  
> the adornment uses a DKTextSubstitutor (new object) to store the  
> "master" string which replaces the earlier label. The user is able  
> to simply embed metadata keys into this string by using a special  
> delimiter (%% in the default implementation). When the string is  
> displayed the metadata value is substituted for the embedded key.  
> The property -identifier is deprecated and older adornment objects  
> automatically convert themselves to the new method in a manner that  
> preserves their original layout. DKTextShape and DKTextPath have  
> been modified slightly so that when editing the text, it is the  
> master string that is passed to the editor. Existing methods of  
> DKTextAdornment automatically deal with the new design - for example  
> -setLabel: passes the text as the master string. The main advantages  
> of this change are that a) values can be substitued anywhere within  
> the text label, not just appended, and b) that any number of  
> embedded keys can be used at once. Note that the ablity to  
> introspect object properties by keypath remains - just prefix the  
> key with a '$' as before, e.g. %%$object.key.path
>
> 56. DKTextAdornment now supports a "knockout" text effect which  
> places a filled and/or stroked outline of the text behind the glyphs.
>
> 57. DKTextAdornment now supports capitalization operations when  
> displaying text.
>
> 58. DKTextADornment now adds a number of its special effects  
> properties as attributes to the normal -textAttributes dictionary,  
> but using keys which are unique to DK, so they can be placed  
> alongside standard Cocoa text attributes. These attributes include  
> the knockout parameters, the vertical alignment parameters and the  
> capitalization settings. These attributes are thus cut-and-pastable  
> as part of a style between objects that are aware of them including  
> DKTextShape and DKTextPath.
>
> 59. DKShapeGroup now checks an object's validity when ungrouping. If  
> the ungrouping causes the object to become invalid, it is discarded  
> rather than be allowed to cause problems. An object is defined to be  
> invalid if it contributes nothing visible to the drawing, so this  
> has no effect on what you see but allows groups to work more  
> robustly. To support this, DKDrawableShape now disallows an invalid  
> path when ungrouping, and deliberately forces itself
> into an invalid state if this occurs. This was a rare occurrence and  
> won't affect the average user.
>
> 60. DKDrawing adds +dearchivingHelper and +setDearchivingHelper: to  
> augment or replace the standard dearchiving delegate. This allows  
> applications using DK to deal with obsolete or replacement classes  
> of their own when dearchiving a drawing. In general it's a good idea  
> to subclass DKUnarchivingHelper if you plan to do this, since that  
> already deals with earlier Drawkit object evolution.
>
> 61. DKCategoryManager also now supports a dearchiving helper.  
> DKUnarchivingHelper has moved to its own source file from DKDrawing,  
> and the internal -changeCount state it was holding has been removed  
> (it was not used anywhere) so the same helper instance can be reused  
> in multiple places if required.
>
> 62. Hit-testing of text objects much improved in terms of accuracy  
> and performance. When hit-testing, the real text isn't drawn but  
> "greeked" text is instead, which doesn't mind about the heavy  
> scaling and bitmap destination context used, and draws faster. The  
> actual greeking effect is implemented by DKGreekingLayoutManager, a  
> new class, used as necessary by DKTextAdornment. Greeked text can  
> also be drawn by DKTextAdornment in normal use also, but since  
> there's very little need for this it currently isn't a persistent or  
> observable property.
>
> 63. DKDrawableObject now explicitly declares the userInfo property  
> as a mutable dictionary. Other parts of DK were already assuming  
> this to be the case. If you are storing any other object type here,  
> you need to revise your code to store the object in the userInfo  
> dictionary using a suitable key. The metadata API that built on this  
> has been revised so that the metadata is stored as an additional  
> dictionary within the userInfo dicitonary, rather than as individual  
> items. Code may need to be revised that was accessing the userInfo  
> directly as the metadata dictionary - a new method, -metadata,  
> returns the appropriate dictionary. This change permits more  
> flexibility when extending a class without compromising the metadata.
>
> 64. DKDrawableObject can now accept a delegate object. DK doesn't  
> use it except to send it messages if it responds to the  
> DKDrawableObjectDelegate informal protocol. This is basically  
> reserved for the use of applications.
>
> 65. Memory leak fixed in DKDrawing export methods.
>
> 66. Bugs fixed with computational geometry on paths. Note that the  
> optional OMNI methods have been found to exhibit an accumulative  
> rounding error which may make them unsuitable when dealing with long  
> paths. Thus in this version they are disabled by default, and the  
> slightly slower, but more accurate DK methods are used.
>
> 67. When copying native objects on the pasteboard, an info object is  
> also stored which can be used to get information about the objects  
> on the clipboard without having to dearchive them. The data type is  
> kDKDrawableObjectInfoPasteboardType. Currently the only info  
> provided is a count of the objects and a breakdown of the classes  
> and the numbers of each. The use of a special helper info object  
> allows this to be expanded simply in the future as needed. Since the  
> count is frequently used to update menus, etc, this is a lot more  
> efficient.
>
> 68. When a DKDrawingView automatically creates the drawing "back  
> end", it now also loads the DKDrawing defaults, which puts in place  
> the standard registered tools. This is an added convenience further  
> reducing the necessary setup for a working DK installation. Even  
> with no UI at all, tool keyboard equivalents function for selecting  
> standard tools.
>
> 69. "Smart" repeated pasting and duplication of objects now works as  
> it was always meant to, by 'predicting' the appropriate offset for  
> the paste.
>
> 70. A drawing's image manager is no longer archived. It's not  
> necessary because each object using image data archives the data,  
> and archiving ensures only a single copy of the same data is placed  
> in the file. The image manager is still needed to handle multiple  
> copies of the same image, but it is noe rebuilt on the fly. As an  
> added bugfix, this change prevents data from images that have been  
> deleted altogether from remaining in the image manager and  
> subsequently getting archived, which was just adding unused content  
> to the file unnecessarily.
>
> 71. Clean-up of a number of memory leaks and incorrectly named  
> methods based on Clang static analyser (thanks to Brad for doing  
> this). Some methods were renamed as a result so they fall into line  
> with proper conventions for memory management - i.e. those including  
> 'create' or 'new' return retained objects or else renamed so that  
> they do not imply this. Some minor code revision of apps using these  
> methods may be needed.
>
> _______________________________________________
> Drawkit mailing list
> Drawkit at lists.apptree.net
> http://lists.apptree.net/listinfo.cgi/drawkit-apptree.net
>



More information about the Drawkit mailing list