c# - Print a Form at higher dpi than screen resolution -


problem:

we need how use winforms' ability auto-scale different dpi’s allow print our forms @ 600dpi, rather @ screen dpi.

for what-you-see-is-what-you-get printing, have been taking our nicely laid out window , printing (turning off scrollbars , buttons , such). works great except 1 thing: comes out @ 96dpi or 120dpi (whatever screen resolution)… either of grainy , unprofessional (our customers complaining). , although readable on screen, expect printed documents more readable on-screen… expect able see additional details, able read smaller text, etc.

alternatives considered:

given have auto-scaling working great, such our window looks in 96dpi, 120dpi, 144 dpi, etc., hoping draw our window @ 600dpi , print that.

or, looked @ drawing window off-screen 5-6x larger normal such have same number of pixels 600dpi, @ 96 or 120 dpi… drawing giant window printed page @ 300 or 600 dpi (whatever printer is).

if can tell how either of alternatives, or if can give different way accomplish our goal, appreciate it.

current code:

in case matters, our form consists of flowlayoutpanel laying other smaller flowlayoutpanels columns, smaller flowlayoutpanels laying out single column of textboxes, richtextboxes, third-party richtexteditor, pictureboxes, , datagridviews. use class derived printdocument implementing onbeginprint, onprintpage, , onendprint. in onprintpage, manipulates our normal window off-screen (below , right of actual screens) fit page size, asks our main panel (the top flowlayoutpanel) drawtobitmap, uses graphics object passed printeventargs drawimage bitmap. use graphics.drawstring apply footer each page. main code:

                    using (bitmap bm = new bitmap(sz.width, sz.height))                     {                         rectangle rect = new rectangle(0, 0, sz.width, sz.height);                         mp.drawtobitmap(bm, rect);                         e.graphics.smoothingmode = system.drawing.drawing2d.smoothingmode.highquality; // footer anti-aliased                         e.graphics.interpolationmode = system.drawing.drawing2d.interpolationmode.highqualitybicubic;  // when scale up, smooth out jaggies                         e.graphics.drawimage(bm, this.marginbounds, rect, graphicsunit.pixel);                         if (this.footer != null)                             e.graphics.drawimage(this.footer, this.footerlocation);                         if (!string.isnullorempty(pagenumber))                         {                             e.graphics.drawstring(pagenumber, kbstyle.normal.font, brushes.black,                                                   this.marginbounds.x, this.footerlocation.y + footeroffset);                         }                     } 

how should 600dpi printed page? (or 300 dpi great!)

when print this, looks far better when printed 120dpi machine when printed 96dpi machine, hence why know printing @ screen resolution. makes wonder if there’s simple way tell “this form should draw @ 600 dpi” , rest of code above works.

note: if grab emf (enhanced metafile) , print printer in code above, emf comes out @ 600dpi. unfortunately, haven’t found drawtoemf method can call on flowlayoutpanel instead of drawtobitmap. changing bitmap 600dpi doesn’t help… drawtobitmap method still seems draw bitmap @ screen resolution.

thanks!!

okay, have figured out... , works great!

i still don’t know how create form @ 300dpi , use auto-scaling functionality.

but…

i have proven if create window 3.125x larger needed @ 96 dpi, , scale font 3.125x, , on, such pixel count you’d need @ 300dpi, though screen @ 96dpi, can use normal control.drawtobitmap() functionality turn bitmap, , can use gdi graphics.drawimage(thatgiantbitmap, giantsrcrect, pagesizedestrect) printer graphics object, , map giant 96dpi pixels page-size 300dpi pixels, giving 300dpi print. perfect.

for of our windows support resizing , let our users zoom contents arbitrarily, printing what-you-see-is-what-you-get easy:

in onbeginprint of printdocument, do:

(1) optionally dup form not mess user looking at

(2) move form want print off-screen (below , right of screens)

(3) set form allowed grow bigger screen size (by default winforms won’t grow larger screen)

(4) divide 300 dpi screen dpi growth factor

(5) grow form growth factor

(6) zoom contents growth factor (if don’t auto-scale / auto-zoom form’s size)

in onprintpage of printdocument, do:

(7) on whatever control in form want print, drawtobitmap() bitmap size of control

(8) on e.graphics drawimage(thatgiantbitmap, giantsrcrect, pagesizedestrect)

that drawimage call draw @ printer’s resolution, if have many pixels in thatgiantbitmap. in case, computed bitmap give number of pixels needed 300 dpi, 300 dpi print-outs if printer 600 dpi. if need full 600 dpi, use 600 dpi in step 4's calculation.


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -