No-frills print to label printer help please

  • I'm writing a small app to print labels. Currently I'm targeting a
    Dymo LabelWriter 400 Turbo (a little USB printer) using a small 2.3" X
    4" label. I created a view in my app that uses that aspect ratio (I
    have yet to find out the printer's actual resolution) at about 315 X
    182. I draw a number of NSStrings in the view at different sizes and
    fonts.

    My first pass at a print routing just calls

    [[NSPrintOperation printOperationWithView: mLabelView] runOperation];

    and it prints, but presents the print dialog and shows a tiny version
    of my view in the center of the page with the wrong orientation (if I
    select "scale to fit paper size" in the Paper Handling section of the
    print dialog; if I don't select "Scale to fit paper size," it shoots
    out one blank label).

    What I want is for my view to scale to fit the entire label, rotated
    to print wide, and i don't want the user to have to deal with the
    print dialog. There will be hundreds of individual labels being
    printed, but all in the same fashion. (There will be a pref for
    setting the printer/label size one time.)

    I'm still reading through the printing docs, but maybe someone can
    point me to the specific things I need to look at to do this right?
    I'm sure there are many ways. For example, I could get the page size
    from the print info record, make the view that size, rotate my text
    and draw. But it seems like there should be an easier way to have my
    view rotated and scaled to fit the page (programmatically).

    TIA,
    --
    Rick
  • I wrote almost this exact same program about 2 years ago.  Looking back at
    the code, here's what I did:
    1) To suppress the print dialog, I called [printOperation
    setShowsPrintPanel:NO] between when I create the print operation and when I
    call runOperation
    2)  To fit the label to the edges I used the
    printOperationWithView:printInfo: variant with a custom print info, and used
    the print info fixer function below to make it print landscape and fit to
    the margins.:

    void FixPrintInfo(NSPrintInfo* thePInfo)
    {
        [thePInfo setOrientation:NSLandscapeOrientation];
        [thePInfo setVerticallyCentered:YES];
        [thePInfo setVerticalPagination:NSFitPagination];
        [thePInfo setHorizontallyCentered:YES];
        [thePInfo setHorizontalPagination:NSFitPagination];

        NSRect pageBounds = [thePInfo imageablePageBounds];
        NSSize pageSize = [thePInfo paperSize];
        float topBottomMargin = MAX(MAX(NSMinY(pageBounds), pageSize.height -
    NSMaxY(pageBounds)), 0);
        float leftRightMargin = MAX(MAX(NSMinX(pageBounds), pageSize.width -
    NSMaxX(pageBounds)), 0);
        [thePInfo setBottomMargin:topBottomMargin];
        [thePInfo setLeftMargin:leftRightMargin];
        [thePInfo setTopMargin:topBottomMargin];
        [thePInfo setRightMargin:leftRightMargin];
    }

    The printInfo supports the NSCoding protocol so I just archived it as data
    after fixing it up and saved it as a preference.  That way you don't need to
    save the printer or the paper size or any of that separately; you just load
    the data from prefs, unarchive it to get the NSPrintInfo object and pass
    that to the printoperation setup routine.

    One other thing I did which might help is, instead of drawing strings into a
    view manually,  I set up a custom view in Interface builder with text fields
    and used bindings to fill in the information.  That way I could use IB to
    layout my label, and still just have a custom view to pass to the print
    operation when it was time to print.

    Best wishes,
    Bo

    PS Keep in mind that the printer's resolution is generally irrelevant as one
    inch is considered 72 point

    On Sun, May 25, 2008 at 1:42 PM, Rick Mann <rmann...> wrote:

    > I'm writing a small app to print labels. Currently I'm targeting a Dymo
    > LabelWriter 400 Turbo (a little USB printer) using a small 2.3" X 4" label.
    > I created a view in my app that uses that aspect ratio (I have yet to find
    > out the printer's actual resolution) at about 315 X 182. I draw a number of
    > NSStrings in the view at different sizes and fonts.
    >
    > My first pass at a print routing just calls
    >
    > [[NSPrintOperation printOperationWithView: mLabelView]
    > runOperation];
    >
    > and it prints, but presents the print dialog and shows a tiny version of my
    > view in the center of the page with the wrong orientation (if I select
    > "scale to fit paper size" in the Paper Handling section of the print dialog;
    > if I don't select "Scale to fit paper size," it shoots out one blank label).
    >
    > What I want is for my view to scale to fit the entire label, rotated to
    > print wide, and i don't want the user to have to deal with the print dialog.
    > There will be hundreds of individual labels being printed, but all in the
    > same fashion. (There will be a pref for setting the printer/label size one
    > time.)
    >
    > I'm still reading through the printing docs, but maybe someone can point me
    > to the specific things I need to look at to do this right? I'm sure there
    > are many ways. For example, I could get the page size from the print info
    > record, make the view that size, rotate my text and draw. But it seems like
    > there should be an easier way to have my view rotated and scaled to fit the
    > page (programmatically).
    >
    > TIA,
    > --
    > Rick
    >
  • On May 25, 2008, at 20:20:38, Boaz Stuller wrote:

    > I wrote almost this exact same program about 2 years ago.  Looking
    > back at the code, here's what I did:

    Thanks Boaz. Did you also override the pagination stuff? What size is
    your view, just some arbitrary size in IB, or do you adjust it based
    on the NSPrintInfo values?

    --
    Rick
  • I don't really remember how I chose the view's size, but I think I set it up
    in IB to be big enough for the label size they were using.  I just ran it,
    and it doesn't scale the image up, only down, so presumably I just made it
    big enough in Interface Builder.  I'd guess that scaling the view to the
    page bounds before each print would accomplish what you're looking for:

    double ScaleViewToPrintPageSize(NSView* labelView, NSPrintInfo* printInfo)
    {
        NSRect pageRect = [printInfo imageablePageBounds];
        NSRect viewRect = [labelView frame];
        double scaleFactor = MIN(NSWidth(pageRect) / NSWidth(viewRect),
    NSHeight(pageRect) / NSHeight(viewRect));
        [labelView scaleUnitSquareToSize:NSMakeSize(scaleFactor, scaleFactor)];
        [labelView setFrameSize:NSMakeSize(NSWidth(viewRect) * scaleFactor,
    NSHeight(viewRect) * scaleFactor)];
        return scaleFactor;
    }
    I haven't tested that, but that should scale up your view to approximately
    the page size.    OTOH, if you know the label size in advance you can just
    multiply the inches by 72 to get the size your view needs to be able to fill
    the label and just create it at least that size. For a 2.34 x 4 label, that
    would be a label 169 x 288, but as long as you preserved the aspect ratio,
    you could make it any amount bigger and still be fine if you use
    NSFitPagination.

    Best wishes,
    Bo

    On Mon, May 26, 2008 at 1:06 AM, Rick Mann <rmann...> wrote:

    >
    > On May 25, 2008, at 20:20:38, Boaz Stuller wrote:
    >
    > I wrote almost this exact same program about 2 years ago.  Looking back at
    >> the code, here's what I did:
    >>
    >
    >
    > Thanks Boaz. Did you also override the pagination stuff? What size is your
    > view, just some arbitrary size in IB, or do you adjust it based on the
    > NSPrintInfo values?
    >
    > --
    > Rick
    >
    >
  • On May 26, 2008, at 07:35:50, Boaz Stuller wrote:

    > I haven't tested that, but that should scale up your view to
    > approximately the page size.    OTOH, if you know the label size in
    > advance you can just multiply the inches by 72 to get the size your
    > view needs to be able to fill the label and just create it at least
    > that size. For a 2.34 x 4 label, that would be a label 169 x 288,
    > but as long as you preserved the aspect ratio, you could make it any
    > amount bigger and still be fine if you use NSFitPagination.

    So, I tried scaling my displayed view just by setting the CTM, and
    that ended up clipping to the view bounds.

    Then I tried creating a new view with the page size values
    (approximately 2288 x 166). For some reason, this *still* prints
    smaller on the page. The printer is actually 300 DPI, and it's as if I
    have to scale to 2.31" X 4" (* 300) to get it to do exactly what I
    want, but now we're working in device coordinates, which seems to go
    against the docs and common sense.

    This is getting to be very frustrating :-(

    Thanks for your suggestions.

    --
    Rick
  • Playing with the CTM won't make your drawing area bigger because your
    drawing area is already clipped to the view's frame by the time your drawing
    code is called.  You need to actually make the view's frame bigger (with
    setFrame: or setFrameSize:) if you want it to show up bigger in its
    superview.

    It sounds like you skipped the part in my first reply where I set the
    margins to  the inset of the imageablePageBounds from the pageSize.  IIRC,
    when I first was writing my app, the print was coming out tiny, and the
    reason was because the print info was defaulting to normal-size (i.e.
    1/2-1") margins, which takes away 1/2 the possible printing area on a 2"
    label.  Once I re-set the margins to properly tiny values, it worked fine.

    Best wishes,
    Bo

    On Mon, May 26, 2008 at 1:24 PM, Rick Mann <rmann...> wrote:

    >
    > On May 26, 2008, at 07:35:50, Boaz Stuller wrote:
    >
    > I haven't tested that, but that should scale up your view to approximately
    >> the page size.    OTOH, if you know the label size in advance you can just
    >> multiply the inches by 72 to get the size your view needs to be able to fill
    >> the label and just create it at least that size. For a 2.34 x 4 label, that
    >> would be a label 169 x 288, but as long as you preserved the aspect ratio,
    >> you could make it any amount bigger and still be fine if you use
    >> NSFitPagination.
    >>
    >
    >
    > So, I tried scaling my displayed view just by setting the CTM, and that
    > ended up clipping to the view bounds.
    >
    > Then I tried creating a new view with the page size values (approximately
    > 2288 x 166). For some reason, this *still* prints smaller on the page. The
    > printer is actually 300 DPI, and it's as if I have to scale to 2.31" X 4" (*
    > 300) to get it to do exactly what I want, but now we're working in device
    > coordinates, which seems to go against the docs and common sense.
    >
    > This is getting to be very frustrating :-(
    >
    > Thanks for your suggestions.
    >
    > --
    > Rick
    >
    >
  • On May 26, 2008, at 11:32:47, Boaz Stuller wrote:

    > It sounds like you skipped the part in my first reply where I set
    > the margins to  the inset of the imageablePageBounds from the
    > pageSize.  IIRC, when I first was writing my app, the print was
    > coming out tiny, and the reason was because the print info was
    > defaulting to normal-size (i.e. 1/2-1") margins, which takes away
    > 1/2 the possible printing area on a 2" label.  Once I re-set the
    > margins to properly tiny values, it worked fine.

    That was it! I didn't expect the default margins to be so huge, so I
    didn't do that part. (I expected the defaults to be what the printer
    indicated it could print to.) I also expected clipping to the margin,
    not scaling of my view to within them.

    Thank you!

    --
    Rick
previous month may 2008 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Go to today