resizing PDF obtained from dataWithPDFInsideRect:

2009-11-19 Thread Chinh Nguyen
I've got an image that's generated using a large integer coordinate  
space.  When it's drawn to the screen, its coordinates are converted  
to screen coordinates.  Unfortunately, the screen coordinates are  
assumed to be integers and it's not a simple fix to use floats (the  
code is common to Mac, Windows, and X Windows).  The code will be  
eventually rewritten, just not anytime soon.


The conversion to screen coordinates is causing stair stepping in  
connected lines and other oddities when exporting to PDF.  As a  
temporary solution until the code is rewritten, I've created a  
subclass of my view that's sized at the large coordinate space's  
dimensions specifically for rendering the image to PDF.  However, I  
can't seem to resize the PDF data down to the more manageable screen  
view's dimensions when saving to disk.  I've tried creating an  
NSPDFImageRep from the PDF data and resizing it but it has no effect  
on the saved to disk image (I guess setSize: does not affect the  
original data).  What I end up with is a PDF file with large  
dimensions that overwhelms whatever application I'm placing it into.


What I ended up doing is creating an NSView subclass that simply draws  
the PDF at the size I want and returns the PDF data from that.  This  
works but is there a better way of resizing the dimensions of PDF data  
or is the size the size that it's generated at and there's no changing  
it?


Also, I allow the user to export the image as a bitmap and even  
override the dimensions.  I create an NSImage from the PDF data,  
resize the NSImage, then save the TIFF representation to the bitmap  
format I want.  This works in Leopard but no longer works in Snow  
Leopard.  I read the tech note about changes to NSImage and caching  
but I had no luck with the different caching methods.  I ended up  
creating an NSImage at the desired size, locking the focus, drawing  
the PDF data at the desired size, unlocking the focus, then saving the  
TIFF representation.  Is there a better way?


And finally, is there a way to change the resolution of a bitmap from  
72dpi to say 300dpi?  My users want to be able to specify the  
dimensions of the exported bitmap in inches and the resolution.  They  
want to be able to place their 1800 pixel wide TIFF file into Word and  
it show up 6 inches wide (@ 300dpi) instead of 25 inches wide (@  
72dpi).  Not a huge deal because I still recommend our users use PDF  
but some of them have legacy apps that don't support PDF.  The example  
I was able to find on this created a new NSBitmapImageRep and copied  
the image data into it and then set the size.


TIA.

-Chinh Nguyen
 cngu...@stata.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


subclassing NSApplication run

2008-12-18 Thread Chinh Nguyen
I know everyone is going to say don't do this but I really need to do  
this.  I need to duplicate the behavior of NSApplication run's event  
handling.  What the docs say about subclassing run is This a critical  
and complex task, however, that you should only attempt with good  
reason. with no further information.  I've got a good reason and I  
can get into more detail about why later if necessary.


My app is a cross platform app (Mac, Windows, and Unix) that all run  
in a single thread and share the same event handling model--the app  
controls the event loop.  The app has an engine that controls  
everything such as processing commands, creating graphs, running  
scripts, displaying help files, etc.  90% of the app's functionality  
must run through the engine which are submitted as commands.  Although  
most of the engine is not reentrant, it makes sure it's in a safe  
state when it polls in case the GUI needs to, for example, create and  
display a programmable dialog from a script on disk that describes the  
dialog while it's already creating a complicated graph.


It's not practical to rewrite this behavior in the app although we're  
taking steps towards instancing up the engine.  However, it'll be  
quite some time before that happens and our users are clamoring for  
the 64-bit version of our app now (necessary for the huge amount of  
data they work with).


I've been working on porting my Carbon app to Cocoa for 64-bit  
support.  Because NSApplicationMain() (and namely, NSApplication run)  
never returns, I created a separate worker thread for the engine to  
run in (the old polling logic is macro'd to nothing).  It's constantly  
looping waiting for commands to be submitted to it (it does idle when  
necessary though).  This works great but the problem is that the  
engine is not thread-safe.  Since neither is AppKit, I'm constantly  
having to make sure methods perform in the right thread otherwise I  
get crashes.  I'm still going through my code to do this and it's  
really tedious.  This biggest issue is that I've found the GUI to be  
quite sluggish in some instances.  For example, the GUI may respond to  
an event by performing code in the worker thread (without waiting, a  
must) which may in turn may perform GUI methods in the main thread  
(while waiting).  Not waiting for methods to perform in the main  
thread speeds things up a little but I haven't confirmed whether  
that's safe yet.


So I've decided to investigate going back to the original single- 
threaded polling model.  To avoid being blocked by NSApplication run,  
I duplicated the behavior of NSApplicationMain() and part of run by  
initializing my NSApplication instance, loading my main nib, then  
invoking finishLaunching.  Control then goes to my engine as before.   
I poll using nextEventMatchingMask:untilDate:inMode:dequeue: and  
sendEvent:.  I just added this earlier today and my app seems to be  
running OK, is much snappier in the situations where it was sluggish  
in the multi-threaded model, and I haven't observed any memory leaks.   
However, I noticed that after a closing a window, the previous key  
window does not become key.  I can add code to handle this but I'm  
concerned there are other things going on in NSApplication's run  
method do/while loop that I'm missing.  Can anyone tell me what else I  
need to do in my event loop?


Again, I can get into more detail about why my app has to behave the  
way it does for clarification.


-Chinh Nguyen
 cngu...@stata.com

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: clearing NSView outside of drawRect:

2008-09-12 Thread Chinh Nguyen


On Sep 11, 2008, at 10:16 PM, Ken Ferry wrote:


If I read this correctly, you're hoping that you can erase some of the
drawing done in your overlay view, just revealing the original drawing
in your complex background view.




You can get the effect you want in layer backed mode (c.f. -[NSView
setWantsLayer:]).  Then each view has its own buffer, so your
selection drawing doesn't wipe out the background drawing, it only
covers it.  You don't need to do anything funky with drawing outside
of drawRect:, though.  Just call setNeedsDisplay: on the parts of your
selection view that need to be redrawn.  This will not cause the
background view to redraw.  It's similar to using an overlay window,
just easier.


Thanks for your suggestions.  Unfortunately, I can't use [NSView  
setWantsLayer:] because I'm trying to support Tiger.  I had assumed  
that views already had their own backing stores which is why I went  
down this route.  Your explanation help clear that up and point me in  
the right direction.


As for using setNeedsDisplay instead of drawing immediately during  
mouseDragged events.  My selection is several pixels behind my mouse  
as I'm dragging it when I use setNeedsDisplay: (when I tried  
setWantsLayer:, it was only a few pixels behind).  When I draw  
immediately, the selection stays right under the mouse as I drag it.   
It's not my background view's drawRect: because I turned it off to  
confirm whether it was the source of the lag and it's not my selection  
view's drawRect: because my test case is simply drawing a line between  
a fixed point and the current location of the mouse.  I have not tried  
a mouse-tracking loop yet.


-Chinh Nguyen
[EMAIL PROTECTED]

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]


clearing NSView outside of drawRect:

2008-09-11 Thread Chinh Nguyen

How do you clear an NSView when drawing outside of drawRect:?

I added and positioned a custom view on top another view  
(addSubView:positioned:relativeTo:) that draws a complex image so that  
I can draw selections in my custom view without having to worry about  
redrawing my original image or using a cached image.  Inside my  
mouseDragged: implementation, I lock my custom view's focus, attempt  
to erase the view using fillRect with clearColor (which doesn't work),  
draw my selection, then unlock the focus.  When that didn't work (and  
I tried returning yes and no for isOpaque), I went ahead and just did  
a setNeedsDisplay:YES on my custom view and just drew the selection in  
drawRect:.  That works but there's a noticeable lag while the mouse is  
being dragged.


In Carbon, I was able to do the above by using an overlay and  
CGContextClearRect().  The only thing I can think of to try next is to  
use similar logic in Cocoa and to place the custom view in a  
borderless window and use NSRectFillUsingOperation(rect,  
NSCompositeClear).  I was hoping to avoid having to do that and deal  
with keeping the two view's positions and sizes in sync.


-Chinh Nguyen
 [EMAIL PROTECTED]

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]