Re: initializing images with view contents, then displaying those images instead of the view
Re: initializing images with view contents, then displaying those images instead of the view
- Subject: Re: initializing images with view contents, then displaying those images instead of the view
- From: Uli Kusterer <email@hidden>
- Date: Sat, 13 Oct 2007 11:32:30 +0200
Am 12.10.2007 um 22:53 schrieb David Harper:
In an effort to improve efficiency in my current project, I have
decided to create NSImages to represent the contents of some of the
subviews in the application. This is a somewhat well-documented
process that I've read about in several different places.
Generally, I've found this approach to be not very useful. In most
cases you'll be much better off finding out which parts of your views
need redrawing, and only redrawing those parts by using
setNeedsDisplayInRect: and querying your view for those rects in
drawRect: (or even just using the argument passed to drawRect: will
often speed up things considerably). Cache the rects of the various
strings so you don't have to measure the text repeatedly, and share
and cache the text system objects instead of having them created and
torn down every time you draw if that still isn't enough.
If you don't redraw everything or rely solely on clipping to cause
things not to draw (which doesn't help, since the text system will
still have to relayout all strings if even one changes, and only the
pixel blitting part won't happen), you will usually get much better
performance. Not drawing is always better than drawing fast.
These views contain dynamically positioned text, and when many of
them are on screen and thousands of individual characters are being
drawn using layoutmanagers etc, the application can gradually slow
down to unacceptable levels (~4 frames per second or lower).
What exactly are you doing? Is this one view that drawAtPoint:s
several strings, or are you creating several NSTextFields (or worse,
NSTextViews???) and why do they have to be updated so much? A user
can't really process that much information, so usually you can get
away with just not showing the information unless the user requests
it (distribute it across several tabs, and only update the fields in
the visible tab, or use floating palettes or other panels or
collapseable panes).
If you're doing animation, you shouldn't be using views anyway,
particularly if you're drawing overlapping views, because that only
almost-works, and will break depending on system setup or phase of
the moon in various ways, and views are too heavyweight to do more
than simple, select GUI-feedback animation.
The solution I've come up with so far works, except that the image
being drawn in the view does not exactly match the one which was
copied using the view's contents... Its width and height seem to
vary by 1-2 pixels.
You're probably drawing between pixels. Are your images also kinda
blurry? Check the archives and NSView docs, it's been explained a
couple of times there, better than I can do right now.
This may have something to do with the fact that the view frame
sometimes has non-integer width and height. I'm not sure if
NSImages are required to have integer NSSize values...
Both views and NSImages are required. There's a piece of
documentation that explicitly warns from creating views of non-
integer sizes. Don't do it. Things will go screwy, you'll get drawing
artefacts from half-erasded lines at the view edges etc.
for some reason, the image created with the code above is
vertically flipped! So I manually unflip it with an affine
transformation using the drawing code below:
Views have an isFlipped method. Have you tried using that?
Cheers,
-- M. Uli Kusterer
http://www.zathras.de
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden