[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