Closed Bug 234470 Opened 21 years ago Closed 20 years ago

There is something wrong with plugin printing on linux or unix

Categories

(Core Graveyard :: Plug-ins, defect, P3)

x86
Linux
defect

Tracking

(Not tracked)

RESOLVED FIXED
mozilla1.8alpha3

People

(Reporter: leon.sha, Assigned: roland.mainz)

References

Details

Attachments

(8 files, 9 obsolete files)

248.96 KB, application/octet-stream
Details
199.13 KB, application/octet-stream
Details
9.83 KB, application/octet-stream
Details
6.71 KB, application/octet-stream
Details
20.80 KB, application/octet-stream
Details
62.48 KB, patch
Details | Diff | Splinter Review
62.76 KB, patch
leon.sha
: review+
Details | Diff | Splinter Review
4.56 KB, patch
dmosedale
: superreview+
Details | Diff | Splinter Review
Bug 198515 was filed for plugin printing. But since bug 225832 and bug 80190, the API for plugin printing changed. Because we can not find a printable plugin for netscape 4, we need a standard for plugin print. First we should make sure that mozilla provide the correct API. And also we should provide a guildline to plugin writer.
Bug 225832 and bug 80190 should not have affected the API for plugin printing. If they did, those were mistakes in those patches and should be fixed. Put another way, did anyone actually test that the fix for bug bug 198515 with an actual plugin that prints? (I should really have asked this back then...) If so, which plugin was it?
I have impletement plugin print into flash player 6.0 adn tested with it. But for some reason it is not included in the release version of flash 6. We have discuss it in bug 198515 about the impletementation. Also we have tested this bug. But with the same impletementation, it does work for mozilla 1.5, but do not work for mozilla 1.6. I am trying to attach a player, but the size is too big. Can I put this to anywhere else? Also about the crash with xprint, I attach the stack below: ________________________________________________________________________________ Program received signal SIGPIPE, Broken pipe. [Switching to Thread 1024 (LWP 10629)] child: (void)fclose(mpfd->file)0x40674a58 in writev () from /lib/i686/libc.so.6 (gdb) child: write(mpfd->pipe[1], &mpfd->status, sizeof(XPGetDocStatus)) child: _exit(EXIT_SUCCESS) (gdb) bt #0 0x40674a58 in writev () from /lib/i686/libc.so.6 #1 0x4077c990 in _X11TransSocketWritev () from /usr/X11R6/lib/libX11.so.6 #2 0x4077d58f in _X11TransWritev () from /usr/X11R6/lib/libX11.so.6 #3 0x4075d495 in _XSend () from /usr/X11R6/lib/libX11.so.6 #4 0x424e5799 in XpPutDocumentData () from /usr/X11R6/lib/libXp.so.6 #5 0x447dd90b in nsXPrintContext::RenderPostScriptDataFragment(unsigned char const*, unsigned long) (this=0x897aff8, aData=0x44889008 "[1250 0 0 -938 540 175] concat\n/picstr 3750 string def\n1250 938 8 [1250 0 0 938 0 0]\n{currentfile picstr readhexstring pop}\nfalse 3\ncolorimage\n", '0' <repeats 57 times>..., aDatalen=7090147) at nsXPrintContext.cpp:1424 #6 0x447de6e7 in nsRenderingContextXp::RenderPostScriptDataFragment(unsigned char const*, unsigned long) (this=0x8962500, aData=0x44889008 "[1250 0 0 -938 540 175] concat\n/picstr 3750 string def\n1250 938 8 [1250 0 0 938 0 0]\n{currentfile picstr readhexstring pop}\nfalse 3\ncolorimage\n", '0' <repeats 57 times>..., aDatalen=7090147) at nsRenderingContextXp.cpp:237 #7 0x412f518d in nsObjectFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x8944874, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffdfd0, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsObjectFrame.cpp:1706 #8 0x412a9e5a in nsContainerFrame::PaintChild(nsIPresContext*, nsIRenderingCont---Type <return> to continue, or q <return> to quit--- ext&, nsRect const&, nsIFrame*, nsFramePaintLayer, unsigned) (this=0x89fdde4, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe380, aFrame=0x8944874, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:274 #9 0x4129a309 in nsBlockFrame::PaintChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fdde4, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe380, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5376 #10 0x412cc902 in nsHTMLContainerFrame::PaintDecorationsAndChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, int, unsigned) ( this=0x89fdde4, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe380, aWhichLayer=eFramePaintLayer_Content, aIsBlock=1, aFlags=0) at nsHTMLContainerFrame.cpp:138 #11 0x41299f74 in nsBlockFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fdde4, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe380, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5249 #12 0x412a9e5a in nsContainerFrame::PaintChild(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsIFrame*, nsFramePaintLayer, unsigned) (this=0x89fdc3c, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe730, aFrame=0x89fdde4, ---Type <return> to continue, or q <return> to quit--- aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:274 #13 0x4129a309 in nsBlockFrame::PaintChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fdc3c, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe730, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5376 #14 0x412cc902 in nsHTMLContainerFrame::PaintDecorationsAndChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, int, unsigned) ( this=0x89fdc3c, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe730, aWhichLayer=eFramePaintLayer_Content, aIsBlock=1, aFlags=0) at nsHTMLContainerFrame.cpp:138 #15 0x41299f74 in nsBlockFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fdc3c, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffe730, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5249 #16 0x412a9e5a in nsContainerFrame::PaintChild(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsIFrame*, nsFramePaintLayer, unsigned) (this=0x89fd910, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffeae0, aFrame=0x89fdc3c, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:274 #17 0x4129a309 in nsBlockFrame::PaintChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fd910, ---Type <return> to continue, or q <return> to quit--- aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffeae0, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5376 #18 0x412cc902 in nsHTMLContainerFrame::PaintDecorationsAndChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, int, unsigned) ( this=0x89fd910, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffeae0, aWhichLayer=eFramePaintLayer_Content, aIsBlock=1, aFlags=0) at nsHTMLContainerFrame.cpp:138 #19 0x41299f74 in nsBlockFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fd910, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffeae0, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsBlockFrame.cpp:5249 #20 0x412a9e5a in nsContainerFrame::PaintChild(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsIFrame*, nsFramePaintLayer, unsigned) (this=0x89fd6ac, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffec80, aFrame=0x89fd910, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:274 #21 0x412a9cb4 in nsContainerFrame::PaintChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fd6ac, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffec80, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:200 ---Type <return> to continue, or q <return> to quit--- #22 0x412a9c53 in nsContainerFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fd6ac, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffec80, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsContainerFrame.cpp:181 #23 0x413097f0 in nsPageContentFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) (this=0x89fd6ac, aPresContext=0x87b1d40, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffec80, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at nsPageContentFrame.cpp:202 #24 0x41319c2f in PresShell::Paint(nsIView*, nsIRenderingContext&, nsRect const&) (this=0x89c0fa0, aView=0x8961430, aRenderingContext=@0x8962500, aDirtyRect=@0xbfffec80) at nsPresShell.cpp:5620 #25 0x4172d6dc in nsView::Paint(nsIRenderingContext&, nsRect const&, unsigned, int&) (this=0x8961430, rc=@0x8962500, rect=@0xbfffec80, aPaintFlags=0, aResult=@0xbfffecbc) at nsView.cpp:260 #26 0x41735977 in nsViewManager::RenderDisplayListElement(DisplayListElement2*, nsIRenderingContext*) (this=0x87e00e0, element=0x89b1430, aRC=0x8962500) at nsViewManager.cpp:1389 #27 0x41735470 in nsViewManager::RenderViews(nsView*, nsIRenderingContext&, nsRegion const&, void*) (this=0x87e00e0, aRootView=0x890c630, aRC=@0x8962500, aRegion=@0xbfffee70, aRCSurface=0x0) at nsViewManager.cpp:1307 #28 0x4173a472 in nsViewManager::Display(nsIView*, int, int, nsRect const&) ( ---Type <return> to continue, or q <return> to quit--- this=0x87e00e0, aView=0x890c630, aX=0, aY=0, aClipRect=@0xbfffef60) at nsViewManager.cpp:3257 #29 0x4132b253 in nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext*) ( this=0x89fd420, aPresContext=0x87b1d40) at nsSimplePageSequence.cpp:903 #30 0x41476f96 in nsPrintEngine::PrintPage(nsIPresContext*, nsIPrintSettings*, nsPrintObject*, int&) (this=0x87ba230, aPresContext=0x87b1d40, aPrintSettings=0x830f940, aPO=0x86e6600, aInRange=@0xbffff03c) at nsPrintEngine.cpp:3573 #31 0x4147fb65 in nsPagePrintTimer::Notify(nsITimer*) (this=0x89c40d0, timer=0x897f890) at nsPagePrintTimer.cpp:91 #32 0x40aacd20 in nsTimerImpl::Fire() (this=0x897f890) at nsTimerImpl.cpp:385 #33 0x40aacee6 in handleTimerEvent(TimerEventType*) (event=0x43a00440) at nsTimerImpl.cpp:447 #34 0x40aa4a54 in PL_HandleEvent (self=0x43a00440) at plevent.c:671 #35 0x40aa48f5 in PL_ProcessPendingEvents (self=0x812dcc0) at plevent.c:606 #36 0x40aa7c2a in nsEventQueueImpl::ProcessPendingEvents() (this=0x80f7fd0) at nsEventQueue.cpp:391 #37 0x41d867a8 in event_processor_callback (source=0x8261560, condition=G_IO_IN, data=0x80f7fd0) at nsAppShell.cpp:67 #38 0x404a97e9 in g_io_unix_dispatch () from /usr/lib/libglib-2.0.so.0 #39 0x4048b2f9 in g_main_dispatch () from /usr/lib/libglib-2.0.so.0 #40 0x4048c2f9 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0 #41 0x4048c613 in g_main_context_iterate () from /usr/lib/libglib-2.0.so.0 ---Type <return> to continue, or q <return> to quit--- #42 0x4048ccb7 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0 #43 0x401e5777 in gtk_main () from /usr/lib/libgtk-x11-2.0.so.0 #44 0x41d86e9a in nsAppShell::Run() (this=0x815f670) at nsAppShell.cpp:142 #45 0x41cac14f in nsAppShellService::Run() (this=0x815e660) at nsAppShellService.cpp:483 #46 0x08067ca3 in main1 (argc=1, argv=0xbffff544, nativeApp=0x812f548) at nsAppRunner.cpp:1291 #47 0x080687ad in main (argc=1, argv=0xbffff544) at nsAppRunner.cpp:1678 #48 0x405c74c2 in __libc_start_main () from /lib/i686/libc.so.6 (gdb)
Status: NEW → ASSIGNED
How big is the player? Do you have no website you could put it on?
Attachment #141509 - Attachment description: Printing job with mozilla1.5 and my flash player. → Printing job with mozilla1.5 and my flash player using PostScript module.
leon sha: The original libflashplayer.so from 15 July 2003 (md5sum = 90cc25b2918f22b8c13a152266c5f614) works perfectly when printing with Xprint - but the new one (md5sum=abf2517d0ce230a5271e0ba498040d4a) causes the following crash: -- snip -- (gdb) run Starting program: /home/gismobile/projects/mozilla/nightlybuildtest/firefox/test001/objdir_gtk1/dist/bin/firefox-bin [New Thread 16384 (LWP 31431)] [New Thread 32769 (LWP 31441)] [New Thread 16386 (LWP 31442)] [New Thread 32771 (LWP 31443)] [New Thread 49156 (LWP 31444)] [New Thread 65541 (LWP 31445)] [New Thread 81926 (LWP 31446)] [New Thread 98311 (LWP 31447)] [New Thread 114696 (LWP 31457)] Gtk-WARNING **: invalid cast from `GtkSuperWin' to `GtkWidget' Gtk-WARNING **: invalid cast from `GtkSuperWin' to `GtkWidget' Gtk-WARNING **: invalid cast from `GtkSuperWin' to `GtkWidget' Gtk-WARNING **: invalid cast from `GtkSuperWin' to `GtkWidget' Gtk-WARNING **: invalid cast from `GtkSuperWin' to `GtkWidget' [New Thread 131081 (LWP 31518)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 16384 (LWP 31431)] 0x40d23170 in PlatformPlayer::NsPrint(_NPPrint*) () from /home/gismobile/projects/mozilla/nightlybuildtest/firefox/test001/objdir_gtk1/dist/bin/plugins/libflashplayer.so (gdb) where #0 0x40d23170 in PlatformPlayer::NsPrint(_NPPrint*) () from /home/gismobile/projects/mozilla/nightlybuildtest/firefox/test001/objdir_gtk1/dist/bin/plugins/libflashplayer.so #1 0x40d27ce1 in NPP_Print () from /home/gismobile/projects/mozilla/nightlybuildtest/firefox/test001/objdir_gtk1/dist/bin/plugins/libflashplayer.so #2 0x40d25900 in Private_Print () from /home/gismobile/projects/mozilla/nightlybuildtest/firefox/test001/objdir_gtk1/dist/bin/plugins/libflashplayer.so #3 0x086e918e in ns4xPluginInstance::Print(nsPluginPrint*) (this=0x97d4908, platformPrint=0xbfffd4f0) at ../../../../../mozilla/modules/plugin/base/src/ns4xPluginInstance.cpp:1128 #4 0x08ac7b93 in nsObjectFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) ( this=0x9bf7cf4, aPresContext=0x9bac458, aRenderingContext=@0x9b79f30, aDirtyRect=@0xbfffd630, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at ../../../../../mozilla/layout/html/base/src/nsObjectFrame.cpp:1668 #5 0x08aa9c98 in nsContainerFrame::PaintChild(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsIFrame*, nsFramePaintLayer, unsigned) (this=0x9bf7804, aPresContext=0x9bac458, aRenderingContext=@0x9b79f30, aDirtyRect=@0xbfffd7b0, aFrame=0x9bf7cf4, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at ../../../../../mozilla/layout/html/base/src/nsContainerFrame.cpp:274 #6 0x08aa0aef in nsBlockFrame::PaintChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) ( this=0x9bf7804, aPresContext=0x9bac458, aRenderingContext=@0x9b79f30, aDirtyRect=@0xbfffd7b0, aWhichLayer=eFramePaintLayer_Content, aFlags=0) at ../../../../../mozilla/layout/html/base/src/nsBlockFrame.cpp:5376 #7 0x08ab4044 in nsHTMLContainerFrame::PaintDecorationsAndChildren(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, int, unsigned) (this=0x9bf7804, aPresContext=0x9bac458, aRenderingContext=@0x9b79f30, aDirtyRect=@0xbfffd7b0, aWhichLayer=eFramePaintLayer_Content, aIsBlock=1, aFlags=0) at ../../../../../mozilla/layout/html/base/src/nsHTMLContainerFrame.cpp:138 #8 0x08aa08b4 in nsBlockFrame::Paint(nsIPresContext*, nsIRenderingContext&, nsRect const&, nsFramePaintLayer, unsigned) ( this=0x9bf7804, aPresContext=0x9bac458, aRenderingContext=@0x9b79f30, aDirtyRect=@0xbfffd7b0, -- snip -- I can't help much more without having debugging symbols or the source code available... ;-(
(In reply to comment #4) > How big is the player? Do you have no website you could put it on? About 1M. Is there any site recommand?
Hrm... just mail it to me at my MIT address.
Yes, it looks like the PS implementation of RenderPostScriptDataFragment() is broken. The coordinate system described in nsIRenderingContext.h is different from the coordinate system that's actually set up. It should be simple to fix; having a way to actually test the function would be helpful, of course. For the record, however, I have reservations with this API. Judging from the postscript samples, the flash player just needs to draw an image. I'm not privy to its internals of course, but perhaps it'd be just as well served by a simple image-drawing API. This would also address something Roland Mainz said in bug 198515, that xprint destinations don't necessarily handle postscript. If we do want to support embedding postscript, it would be far better to support the encapsulated postscript format rather than this homegrown standard. EPSF is a mature standard, and it's well-documented; see http://partners.adobe.com/asn/developer/pdfs/tn/5002.EPSF_Spec.pdf>.
I have to put in a vote for EPSF too, if we can swing that. Roland, will XPrint deal?
Attached file gziped EPSF file 1
In general the plugin printing design appears in need of "stop, lets think what we need". FYI If you are looking for something to test with, Sun's JDK 1.4.2 plugin for Solaris and Linux printed just fine in Netscape 4.79. That's not to say it was easy to figure out netscape's requirements for coordinate system etc. And netscape had problems too. Multi-page plugin printing (where a web page is "long" and the plug-in content spanned printed media pages) worked "so-so" because netscape would lie about where the page break was. It would clip printed output so that HTML text lines didn't appear partially on one page and partially on the next. By not communicating the true clipped area a plug-in had no chance. Also the multiple "layers" (never adequately explained to me) meant a plugin would be called 3 times and only on the 3rd time - typically - should it in fact print. However mozilla for a long time simply didn't support plugin printing. 1.5 and 1.6 do only sort of on Unix. For no apparent or justifiable reason it was changed from the netscape coordinate system, thereby breaking every piece of plugin-printing code. Moreover 1.5 and 1.6 are both broken differently so, making it essentially impossible to know what to target. wrt the comments about EPSF. The Java plugin already used encapsulated postscript and netscape 4 supported it. Also note that mozilla as did netscape emits postscript procedures BeginEPSF and EndEPSF. Before touching code specify and agree: - the coordinate system - what the PS clip is set to - what may be inferred - what window.x/y/width/height mean - whether and when to call BeginEPSF/EndEPSF - how to handle page-spanning Also the ability of mozilla to locate printers is a mystery. It ought to locate the system printers. Never does for me. Needs to work out-of-the-box. Another issue is Print Preview - it apparently has no implementation, but that's for another day. BTW Who "owns" this module?
> For no apparent or justifiable reason it was changed from the netscape > coordinate system Because the people who implemented it had no idea what Netscape's coordinate system was, really. If you know what it is, please post in this bug. That would help tremendously. The first three items on your list are absolutely blockers for the plugin printing impl (as I keep trying to tell Leon, without much success as far as I can tell). The page-spanning issue is nasty because it's so hacked-in in Mozilla code in general. But it does need to be solved, yes.... We should figure that out once we sort out the first three items (and before we make any code changes, as you said). As for who owns this.... it's currently unowned (Brendan, please correct me if I'm wrong). I guess the generic layout owners are the closest it has to owners.
(In reply to comment #12) > In general the plugin printing design appears in need of > "stop, lets think what we need". > > FYI If you are looking for something to test with, Sun's JDK 1.4.2 plugin > for Solaris and Linux printed just fine in Netscape 4.79. > That's not to say it was easy to figure out netscape's > requirements for coordinate system etc. And netscape had problems too. > Multi-page plugin printing (where a web page is "long" and the plug-in > content spanned printed media pages) worked "so-so" because netscape would > lie about where the page break was. It would clip printed output so that > HTML text lines didn't appear partially on one page and partially on the next. > By not communicating the true clipped area a plug-in had no chance. > Also the multiple "layers" (never adequately explained to me) Where did you get that comment from (URL) ? > meant a plugin > would be called 3 times and only on the 3rd time - typically - should it in > fact print. Well, the correct behaviour with the current API would be that a plugin which spans over multiple pages should be called for each single page and render it's content and the caller (e.g. mozilla) is responsible to clip the content to show only the visible part of the plugin for that specific page. > However mozilla for a long time simply didn't support plugin printing. > 1.5 and 1.6 do only sort of on Unix. > > For no apparent or justifiable reason it was changed from the netscape > coordinate system, thereby breaking every piece of plugin-printing code. Complain to Kenneth Herron, please. The coordinate space of the PostScript module was changed in 1.6, breaking backwards compatibility (one of the three reasons why dcone designed it in that way) and lots of other things (like postprocessors for Mozilla's PostScipt output) ... ;-( > Moreover 1.5 and 1.6 are both broken differently so, making it > essentially impossible to know what to target. You will have to deal with more than one print module on Linux/Unix mozilla anyway (Xprint module and PostScript module) and we have to be compatible to Konqueror and Opera, too... [snip] > Before touching code specify and agree: > - the coordinate system > - what the PS clip is set to - what may be inferred > - what window.x/y/width/height mean > - whether and when to call BeginEPSF/EndEPSF > - how to handle page-spanning See comment above. IMO page-spanning can only be implemented correctly via calling the plugin's print code for each page seperately (and clip the visible area), otherwise we will not be able to handle different page geometries correctly (e.g. CSS@page can change the page geometry between pages. Currently this is not fully be implemented but we should be prepared for it :) > Also the ability of mozilla to locate printers is a mystery. > It ought to locate the system printers. Never does for me. > Needs to work out-of-the-box. The "builtin" PostScript print module is unable to do that (and will never able to do (details on demand) ... ;-/). Grab and install http://xprint.sourceforge.net/download/009release/GISWxprint-sparc-2004-02-16-release_009.tar.gz and Mozilla should find all your printers automagically (documentation can be found at http://xprint.mozdev.org/ and http://www.mozilla.org/projects/xprint/). > Another issue is Print Preview - it apparently has no implementation, > but that's for another day. For PrintPreview we could grab the onscreen image of the plugin... :) > BTW Who "owns" this module? AFAIK no one currently. rods@netscape.com, dcone@netscape.com and attinasi@netscape.com were the module owners for crossplatform print code, dcone@netscape.com wrote the PostScript module, I and katakai wrote the Xprint module... unfortunately dcone, rods and attinasi are AFAIK no longer working on mozilla...
(In reply to comment #8) > For the record, however, I have reservations with this API. Judging from the > postscript samples, the flash player just needs to draw an image. You're assuming that all plugins behave like that... what if a future version of the flash plugin (which is currently an experimental version!) is able to do real PostScript vector output ? > I'm not privy > to its internals of course, but perhaps it'd be just as well served by a > simple image-drawing API. Please do some simple math: 600 DPI/DIN-A4 results in a 6600x6600 pixel wide surface (quadratic in this case to handle per-page orientation changes). If we assume the plugin is prints nearly full-page we get: 6600px * 6600px * 24bit = ~~332.34MB That's likely a DOS-attack against any printer. We would have to reduce the resolution (and therefore the resulting quality on paper) and use compression within the PostScript job (making printing much slower) to avoid that issue. And we would haved to define a new API, too. > This would also address something Roland Mainz said in bug > 198515, that xprint destinations don't necessarily handle postscript. For PostScript DDX of Xprint supports it (we're mainly discussing PS output right now, the PDF/PCL/SVG DDX may not be able to support that but I guess that's acceptable for now).
> Also the multiple "layers" (never adequately explained to me) It's pretty simple, actually. And the CSS spec explains it fairly well. Essentially, when you paint a region you first go and paint all the backgrounds in a preorder depth-first traversal of the tree. Then you go and paint all the foregrounds in the same traversal. The idea is that the text of any node should be above the background of any other node. As for splitting... there are several ways it could be done, not just with clipping. For example, Roland, see what nsImageFrame does. That would require a way to ask a plugin to print a certain subrect of itself, but that could be added to the API we have for printing plugins if that's the way we decide to go. > The coordinate space of the PostScript module was changed in 1.6 Coordinate space changes are the least of it (and easily fixable, I must add). You and Leon still haven't answered my repeated questions about what the coordinates _should_ be. Ccing roc and dbaron, since they should be in on this discussion, in my opinion....
> Before touching code specify and agree: > - the coordinate system > - what the PS clip is set to - what may be inferred > - what window.x/y/width/height mean > - whether and when to call BeginEPSF/EndEPSF > - how to handle page-spanning I'd vote for EPSF. I'd also vote for a clipping solution to the page-spanning problem: it's trivial for the plugin writer to handle, and gives Mozilla full control.
(In reply to comment #17) > > Before touching code specify and agree: > > - the coordinate system > > - what the PS clip is set to - what may be inferred > > - what window.x/y/width/height mean > > - whether and when to call BeginEPSF/EndEPSF > > - how to handle page-spanning > > I'd vote for EPSF. I'd also vote for a clipping solution to the page-spanning > problem: it's trivial for the plugin writer to handle, and gives Mozilla full > control. So, can we make an agreement now? We will use EPSF? Or still need vote? If so, can we start vote?
There have been a number of updates/comments here since my last post. I won't respond to them individually but will try to cover the most important points as best as I can. I don't know how useful it will be. I was asked what was netscape's coordinate system for Postscript plug-in printing. Here's what I noted in a Sun bug report (4523274) I don't have any special knowledge here, I inferred it all from what I saw happening. - netscape sets a postscript clip from which page size can be derived - nescape does not translate to the origin of the applet before printing it - netscape defines but does not call BeginEPSF and EndEPSF procedures - netscape calls 3 the plugin times to print, but only the 3rd call should be used. ie print only if (call# % 3 ==0) Here's a snippet of postscript code generated by Netscape's own Java VM in Netscape 4.78 on Solaris 9 for a Java applet defined to be 100x100 pixels in size embedded near the top of a web page. It actually appears to be approximately at (0,85) in the HTML canvas. ========= BeginEPSF 0 634.1 moveto 70 0 rlineto 0 -70 rlineto -70 0 rlineto closepath clip 0 564.1 translate 0.7 0.7 scale %%BeginDocument: JavaApplet %!PS-Adobe-3.0 EPSF-3.0 %%Title: TestApplet %%BoundingBox: 0 0 100 100 ============== All of that was emitted by the Plugin printing code, not the main HTML page printing code. - It starts with BeginEPSF - a netscape defined procedure also in mozilla - Note that "y" increases up the page - the normal postscript orientation The scaling transformation appears to be the default (ie sx=1, sy=1) so the "0 634 moveto" sets currentpoint 8.81 inches up from the bottom left - It defines a clip that encompasses the area of the page containing the plugin content. - It translates to "0 564" which is the "bottom left" of the applet (ie plugin) content. - There's a 0.7x0.7 scale applied so that the 100x100 pixel applet scales into the 70x70 page area specified. Specified where you ask! Its not seen here but the window passed in the NPPrint structure has x/y/width/height specified in this case as x=0, y=85, w=70 h=70. 70x70 isn't the on-screen window size. This is the user space page area into which you are asked to print. I guess its assumed the applet knows its own size. I don't know if netscape's VM just "knows" to say "0.7 0.7 scale" or if their VM also derived it as I calculated it as window.width/applet.width. (0,85) corresponds to the position in the web page - It emits an EPSF header in conformance with the Adobe document structuring conventions, including the bounding box specifying the size of the applet in its own coordinate space. - The window x,y is "web page" coordinates so that if a web page were very long and a plug-in were to be printed on the 2nd page you'd have to infer that
(In reply to comment #19) > and a plug-in were to be printed on the 2nd page you'd have to infer that oops that's not my whole message : here's the rest .. - The window x,y is "web page" coordinates so that if a web page were very long and a plug-in were to be printed on the 2nd page you'd have to infer that all pages are the same size and use the clip to figure out the imageable area of the page and take the modulus of the y position of the applet and the imageable area. In my printing implementation I calculated it like this: stream.println("BeginEPSF"); // defined by Netscape 4.x stream.println("%%BeginDocument: JavaPluginApplet"); stream.println("clippath pathbbox"); stream.println("/ury exch def /urx exch def"); stream.println("/lly exch def /llx exch def"); stream.println("/imHgt ury lly sub def"); stream.println("/ypos ury " + (by+bh) + " imHgt cvi mod sub def"); stream.println("llx ypos translate"); where by and bh are the NPPrint window "y" and "height" As someone suggested I think I relied on the postscript clip to ensure that only the content for this page were actually printed. Since this relies on all pages being the same it should be allowed that this technique continue to work in that typical case, but that there also be some way to find out exactly where you are to print on this page to support cases where not all pages are the same size. Perhaps if prior to calling the plugin, there was a translate to the top-left of the plugin area. ie the statement to the plugin author is "the currentpoint corresponds to where the top-left of the plugin should be drawn". The plug-in author then would not (should not) translate. Then the plug-in writer wouldn't have to worry about multi-page drift, page-spanning etc. The browser has figured out exactly where the plugin is to be placed no matter what page you are on (multi-page drift) If a plugin were to span pages, then the translate would of course be different for each invocation. postscript would clip the output. The plugin would simply duplicate its contents at each location (Is there a way to avoid this? Perhaps not a terribly importantcase) On the subject of page spanning, I misremembered something (it was 2 years ago). Specifically I didn't figure out page spanning properly. The problem related to the "mystery" I referred to that netscape calls the plugin 3 times once for each layer bzbarsky tried to help by explaining layers but what they are but I'm not sure that helped me any with what I was seeing in netscape since mozilla is NOT the same. Here's a snippet from my evaluation at that time: ====== 2. applets which span a printed page boundary. The "print on the 3rd call" rule breaks down here. Applets which span a page boundary are called 5 times, the 1st 3 should be ignored and you print on the 4th and 5th. The 4th presumably intended for the bottom of one page, the 5th for the top of the next. You can't know that the call spans a page boundary since netscape isn't giving you page dimension information. So you have no way of knowing you are going to be called a 4th or 5th time until it happens, and by then the PS is already emitted - in the wrong place (ie at the head of the PS file stream). Also since the info Netscape passes you is identical in the 4th and 5th cases, you wouldn't know if you need to print at the top of the page or the bottom. You would have to track that you were called already and that the output would not fit on the page, and somehow adjust. But you need to distinguish that from a case where the user simply prints the page twice. There's not nearly enough information to do all of this, so I basically gave up trying to make this case work. You will get unusable postscript. Hope netscape does better in 6.x ====== So I couldn't make sense of what was going on. Note that Netscape's VM seems to manage it for an applet that spanned page 1 & 2. But one that spanned page 2 & 3 was missing the page 3 content. So they couldn't work with their own code .. So this is one "different" thing that is a potential improvement in mozilla. Yes, each page must be printed separately when the page is spanned, as a separate EPSF document. This has to be how it works because you can't move to the next page yourself with a showpage from the EPS netscape's Java VM. That's what I tried to do but it broke down because of the problems above. Print Preview may be implemented by a "screen capture" but that will work only so long as the API you have for the screen capture knows what the pixels are. Consider an OpenGL-based plug-in - are the APIs to get the pixels from X11 going to work properly there? They could if the Xserver did it right and you wrote code that didn't assume the same visual for that plugin subwindow as the rest of the browser window. Also this isn't going to work well for people who want to make use of a "zoom" functionality in print preview. IE provides this and it applies to plugins as well as the rest of the page. Personally I'd be inclined to accept that as a limitation just to get basic preview functionality
One more point about the coordinate system in netscape. If the user specified "landscape" then there is a rotation already applied so its transparent to the plugin author. i.e you can treat it as "portrait" but with paper that just happens to be wider than it is long.
Phil, thank you for the information! That should be very helpful! I bet the 0.7 scaling factor corresponds to the difference between the screen dpi and the "72dpi" that postscript ostensibly defaults to....
I wanted to see just what kind of postscript the java plugin emits, so I started netscape 4.75, loaded the java control panel page, and printed it to a file. The plugin output is normal EPSF, wrapped in the setup stuff described in comment 20. If we adopted EPSF as the standard format, then the mozilla version of the plugin could just drop the BeginEPSF/EndEPSF wrapper stuff and just output the EPSF part. The mozilla printing implementation would parse the bounding box from the plugin output and generate the correct wrapper code. For the gfx rendering interface, it seems to me we just need an nsRect describing where on the page the plugin's PS should go, along with the text of the EPSF. Currently, the plugin writes its output to a file, while |RenderPostScriptDataFragment()| receives the fragment in a buffer. This means |nsObjectFrame::Paint()| has to allocate a buffer and read in the EPSF. Perhaps we could simplify this and just pass the EPSF file handle to the rendering function. Regarding print preview, there are a couple of things we could do. EPSF supports an optional thumbnail image embedded in the EPSF for just this sort of situation. If the EPSF provided by the plugin included a thumbnail, mozilla could display that. Alternately, mozilla could launch ghostscript to render the EPSF into an image. The xdvi program (an X windows viewer for TeX documents) has had this capability for years.
Attached patch EPS support proof-of-concept (obsolete) — Splinter Review
This is just for illustration purposes. It removes the RenderPostScriptDataFragment() function from the rendering context interface, adding RenderEPS() in its place. It includes a simple implementation for the PS print driver. I've also hacked the image-drawing routine to embed an EPS file "/tmp/test.ps" in place of any image.
CNN.com printed with the EPS patch, using a simple low-res bitmap EPS I had lying around.
> Perhaps we could simplify this and just pass the EPSF file handle to the > rendering function. Sounds like a good plan in case plugins want to generate really huge output (I can imagine PDF plugins wanting to, for very complex documents). Having the translation origin be the top left corner of the plugin sounds like totally the right thing. I think we don't currently support page-spanning plugins. To do that right we'd have to make nsObjectFrame splittable; the next-in-flows would have to share the plugin instance of the first-in-flow. Currently I suppose we just bump plugins to the next page and plugins bigger than a page overflow. Would we really want to make plugins splittable? Whether we do or not, the plugin API should be designed so plugins do not need to know or care about page spanning (i.e., if we need to draw the plugin on two pages, we'll include its Postscript output twice with whatever translations and clipping are necessary).
One more thing to think about: SVG is coming. Ultimately we want to be able to print a plugin inside an SVG foreignobject inside an SVG filter (e.g., an SVG filter might designate the entire foreignobject as a group to be rendered translucently onto the canvas). I'm told that Postscript itself cannot handle this kind of rendering, but that PDF can (well, for some subset of the SVG filters). If we were to move to a PDF rendering target, would EPSF work in the above scenario?
Another thing to note is that that world is going to require plugins be able to render into an RGBA buffer that Mozilla do arbitrary rendering transformations on. We could just print that buffer, for plugins that don't require really high resolution output.
> If we were to move to a PDF rendering target, would EPSF work in the > above scenario? No. PDF supports embedding PDF and JPEG, but not EPSF.....
this patch is based on "EPS support proof-of-concept" patch. it pass plugins a FILE pointer, get EPS content from plugin, then print it. if plugin generates valid EPS content, plugin printing on linux/unix will be ok.
Comment on attachment 144729 [details] [diff] [review] patch for plugin printing on linux/unix bz, this is for you :-) Please let me know if you don't have time. Thanks!
Attachment #144729 - Flags: superreview?(bzbarsky)
this is a demo plugin. I put it below directory "mozilla/modules/plugin/samples/", and it works well on my computer. "plugin.html" is the sample html using demo plugin.
Comment on attachment 144729 [details] [diff] [review] patch for plugin printing on linux/unix This patch has a bunch of issues: 1. I said that many times before, I say it again: NEVER pass the |File *| passed to the plugin as-is to the gfx/ code. The |File *| is in an unknwon state so it should be at least be reset to file position 0. 2. the patch completely misses support for Xprint
Attachment #144729 - Flags: review-
Attachment #144729 - Flags: superreview?(bzbarsky)
(In reply to comment #33) > 1. I said that many times before, I say it again: > NEVER pass the |File *| passed to the plugin as-is to the gfx/ code. The |File > *| is in an unknwon state so it should be at least be reset to file position 0 The comments for |nsIRenderingContext::RenderEPSF()| don't document a requirement to rewind the file before calling the function, and the PS implementation handles the issue by rewinding the handle itself. Even if we documented a requirement for the caller to rewinde the handle first, it's not an expensive operation. It's simple defensive programming for the implementation to do it, so there's little value in requiring the caller to do it. Specifically what other concerns do you have here? Anything else that the plugin could do to the handle, such as closing it, would affect the current implementation just as well as the patch. If this is such a concern, it seems to me the real solution is not to pass a file handle to the plugin in the first place. > 2. the patch completely misses support for Xprint Well, the PS maintainer provided an initial PS implementation. Who do you believe should provide the xprint implementation? The java, flash, and other plugin maintainers all have their own release cycle to consider, so there is value in finalizing the design whether or not it's fully implemented in mozilla.
(In reply to comment #34) > (In reply to comment #33) > > 1. I said that many times before, I say it again: > > NEVER pass the |File *| passed to the plugin as-is to the gfx/ code. The |File > > *| is in an unknwon state so it should be at least be reset to file position 0 > > The comments for |nsIRenderingContext::RenderEPSF()| don't document a > requirement to rewind the file before calling the function, and the PS > implementation handles the issue by rewinding the handle itself. Even if we > documented a requirement for the caller to rewinde the handle first, it's not an > expensive operation. It's simple defensive programming for the implementation to > do it, so there's little value in requiring the caller to do it. We simply do not know what the plugin does when writing to the FILE handle... does the plugin only use fputs(), does it use mmap() and then write to the mmaped() memory... does it use fseek() for any purpose ? It's completely undefined what the plugin can use. Mozilla should protect itself against that and other problems - remeber we're calling here unknown (or better: "alien") code which is maintained outside the Mozilla codebase. And passing a |FILE *| handle to the print modules and let each print module then copy that data to the output stream is just stupid because it assumes that the print API being used accepts a |FILE *| as input. But the majority of print APIs (assuming that we may want to support GnomePrint and QPrinter some day) take a |char *string| and a |size_t length| parameter as input. Therefore my suggestion is to put the data of the temp. file into a string (or if someone complains about performance - mmap() it) and pass the string and the length to gfx. That will protect Mozilla from any weird actions done by plugins writing to the |FILE *| (and keeps that code in a central location) and passes a string around. > > 2. the patch completely misses support for Xprint > > Well, the PS maintainer provided an initial PS implementation. Who do you > believe should provide the xprint implementation? The java, flash, and other > plugin maintainers all have their own release cycle to consider, so there is > value in finalizing the design whether or not it's fully implemented in > mozilla. Right now plugin printing works with Xprint so the current patch would regress that functionality and I doubt that a patch is going to be approved by anyone which introduces new regressions (weired... you have CVS write access and don't know the rules or what ?).
Taking myself
Assignee: peterlubczynski-bugs → roland.mainz
Status: ASSIGNED → NEW
Status: NEW → ASSIGNED
Priority: -- → P3
Target Milestone: --- → mozilla1.8alpha
Comment on attachment 144731 [details] demo printable plugin for unix/linux(unixPrint.tar.gz) I am moving this part to a seperate bug (bug 238704 - "RFE: Need sample plugin for plugin printing") ...
Attachment #144731 - Attachment is obsolete: true
Depends on: 238704
Comment on attachment 144729 [details] [diff] [review] patch for plugin printing on linux/unix I'll try to make a new patch...
(In reply to comment #35) > We simply do not know what the plugin does when writing to the FILE handle... > does the plugin only use fputs(), does it use mmap() and then write to the > mmaped() memory... does it use fseek() for any purpose ? It's completely > undefined what the plugin can use. As far as I'm concerned, the plugin can do any of the documented things you can do with a file handle, except of course for closing it. If there's some dangerous little stdio feature I've forgotten, then it may be necessary to restrict that policy, but this stuff isn't voodoo. Do you have an actual example of something wrong the plugin could do with the file handle, or is this all hypothetical? If your concern is that the plugin could dereference the pointer and corrupt the FILE structure, well, the boat sailed on that level of paranoia when they decided to run plugins in-process. > And passing a |FILE *| handle to the print modules and let each print module > then copy that data to the output stream is just stupid because it assumes that > the print API being used accepts a |FILE *| as input. But the majority of print > APIs (assuming that we may want to support GnomePrint and QPrinter some day) > take a |char *string| and a |size_t length| parameter as input. Moving data between a file and an in-memory buffer is a straightforward operation, no matter which way you're moving it. I'm sure you're aware of this. Right now the plugin interface requires the plugin to write the data to a temporary file, then layout rewinds the file and reads the data into a buffer. Are you saying it's safe to do these things in layout, but dangerous to do them in gfx? Or are you saying you want to change the plugin API to get rid of the temporary file entirely? > Therefore my suggestion is to put the data of the temp. file into a string (or > if someone complains about performance - mmap() it) and pass the string and the > length to gfx. That will protect Mozilla from any weird actions done by plugins > writing to the |FILE *| (and keeps that code in a central location) and passes a > string around. If everyone thinks mmap() is portable enough to use it here, then fine. Otherwise, if the gfx module can handle either format just as easily, or if it doesn't implement rendering postscript fragments, then you've done this potentially huge memory allocation (up to 128MB in the current implementation) and file I/O for nothing. The best approach is to leave the data in the form it's produced by the plugin for as long as possible. If the printing module needs to convert it somehow, well, that is its job. Doing a particular data conversion speculatively, just because some hypothetical future gfx interface might prefer it in that format, is bad software design. > > > 2. the patch completely misses support for Xprint > > > > Well, the PS maintainer provided an initial PS implementation. Who do you > > believe should provide the xprint implementation? The java, flash, and other > > plugin maintainers all have their own release cycle to consider, so there is > > value in finalizing the design whether or not it's fully implemented in > > mozilla. > > Right now plugin printing works with Xprint so the current patch would regress > that functionality and I doubt that a patch is going to be approved by anyone > which introduces new regressions (weired... you have CVS write access and don't > know the rules or what ?). My understanding is that right now, we have an interface which specifies a mozilla-specific postscript environment, presumably works correctly for xprint, doesn't work correctly for ps, and is implemented by just about nothing available to the public. Are you saying that you want to stick with the current interface, instead of moving to an EPSF-based interface? Why? I've already said I'll fix the ps module if that's the consensus. But I think we have an opportunity here to improve on a bad design and to make things easier for plugin writers, and we should take it even if it means a bit more work for us. As far as the gfx rendering interface is concerned, we could support the existing function as well as a new EPSF-rendering function. The real question is which postscript environment should be targetted by plugins? Are they going to output postscript for the existing, half-documented, nonstandard postscript environment? Or are they going to output an EPSF?
Roland Mainz, thank you for your comments. I have looked at source code for xprint, it uses RenderPostScriptDataFragment, and parameters are (char * ,length).Now I change interface to RenderEPS and that causes some problems for xprint. I think we should coorporate and work out a solution both for ps and xprint. There are three things we should focus on. 1.what kind of contents should the plugin provide to mozilla? there are lots of comments on this topic. almost all people think the EPS is better than the current implement.and what's your idea? 2.what should we pass to plugin? current plugin's APIs use | FILE* |.I think APIs should be as constant as possible, so I still pass FILE pointer to plugin. DO you think we should pass buffer to plugin? Since we don't know buffer length, perhaps more work should be done if we use buffer. 3.what should we pass to RenderEPS or RenderPostScriptDataFragment? You and Kenneth Herron have talked a lot about it. You think FILE * may causes error for gfx so buffer is needed. Kenneth Herron thinks if FILE * causes no error for layout, it should cause no error for gfx; or if layout can handle it, gfx can also has the ability to handle it; what is more, this allocating action may completely be waste of resources, so it should be delayed as possible as we can. what's your idea about the above questions? perhaps we can work together to make up this patch.
I agree with Kenneth and can't think of any special risks from passing a FILE* to gfx.
I have modified xprint part, and create this patch. For I don't have write access, you have to copy "nsEPSObject.cpp" && "nsEPSObject.h" from "mozilla/gfx/src/ps/" to "mozilla/gfx/src/xprint/". This patch should work with the demo printable plugin.
The patch adds support for both Xprint module and PostScript module. I still have to look at dantifier's patch and merge both since mine predates his work (dantifier: again, sorry for the long delay...).
Attachment #143311 - Attachment is obsolete: true
Attachment #144729 - Attachment is obsolete: true
(In reply to comment #43) > attachment 144904 [details] [diff] [review])">Created an attachment (id=145772) > Patch for 2004-03-25-trunk (this predates attachment 144904 [details] [diff] [review]) > > The patch adds support for both Xprint module and PostScript module. I still > have to look at dantifier's patch and merge both since mine predates his work perhaps this patch failed to accomplish the goal. 1. PS module only supports EPSF format. If 'nsEPSObjectPS' can not find boundbox tag, it will set mStatus = NS_ERROR_INVALID_ARG; then NS_ENSURE_SUCCESS(eps.GetStatus(), NS_ERROR_INVALID_ARG) will fail. 2. nsObjectFrame passes 'aDirtyRect' to plugin. So plugin can not determine its absolute position in the whole page. so traditional method can not work any longer, even with xprint. 3. This back-compatible solution may cause more confusion in the future. And I think using (char*,length) to replace (File*) brings no benefit but latent extra cost. > (dantifier: again, sorry for the long delay...). That is OK. :)
Attached patch New patch for 2004-05-02-trunk (obsolete) — Splinter Review
Attachment #144904 - Attachment is obsolete: true
Attachment #145772 - Attachment is obsolete: true
Attachment #148414 - Flags: superreview?(roc)
Attachment #148414 - Flags: review?(dantifer.dang)
Robert O'Callahan wrote: > I agree with Kenneth and can't think of any special risks from passing a FILE* > to gfx. kherron's patch completely violates ideas like "abstraction" and "encapsulation" usually common in C++ applications. Using the Unix-plugin-API-specific |FILE *| handle around is like putting GTK+-toolkit functions all over layout/. Sure... if you allow that we can talk about passing the |FILE *| hanle around between different API layers in Mozilla... :)))) IMHO the implementation details of the Unix plugin printing API should be hidden away from the gfx/ layer - that's a much cleaner and easier solution than passing the |FILE *| handle around and duplicating the processing code for that handle over all print modules (and parsing the file multiple times, too). That's a horrible hack I'd like to avoid.
ZF.Dang wrote: > (In reply to comment #43) > > attachment 144904 [details] [diff] [review])">Created an attachment (id=145772) > > Patch for 2004-03-25-trunk (this predates attachment 144904 [details] [diff] [review]) > > > > The patch adds support for both Xprint module and PostScript module. I still > > have to look at dantifier's patch and merge both since mine predates his > > work > > perhaps this patch failed to accomplish the goal. > 1. PS module only supports EPSF format. If 'nsEPSObjectPS' can not find > boundbox tag, it will set mStatus = NS_ERROR_INVALID_ARG; then > NS_ENSURE_SUCCESS(eps.GetStatus(), NS_ERROR_INVALID_ARG) will fail. > 2. nsObjectFrame passes 'aDirtyRect' to plugin. So plugin can not determine > its > absolute position in the whole page. so traditional method can not work any > longer, even with xprint. The x,y-offset has changed... but we can detect whether the PostScript data from the plugin are EPSF or not... and for non-EPSF data we can simply add a small piece of PS code which adjusts the X,Y coodinates - and then even the "old way" works again. > 3. This back-compatible solution may cause more confusion in the future. > > And I think using (char*,length) to replace (File*) brings no benefit but > latent extra cost. See my previous comment. Kherron's way exposes implementation details of the Unix plugin API down to the gfx/ layer - which should never be done like that. And it processes the PS data multiple times, too - which isn't very efficient either (it's debateable whether the current solution can be made better... I wish there would be a portable way to use |mmap()| - that would completely avoid the need for allocating any extra buffers first...).
FILE* belongs to libc. There is nothing Unix specific about it. The only Unix specific thing here is that it's on Unix that plugins produce EPS that needs to be passed to Gfx. Once we've decided to add EPS support to Gfx interfaces, then as far as "abstraction" and "portability" are concerned, FILE* is as good as char*. (I would not have any problem if we decided to start passing FILE* around in Mozilla, except that we have our own stream classes that are a bit better, but the're not suitable here.) > And it processes the PS data multiple times, too - which isn't very efficient > either Who cares? The main thing is that the code be simple and correct. Speed of printing plugins is never going to be a major performance bottleneck.
Kenneth Herron wrote: [snip] > Right now the plugin interface requires the plugin to write the data to a > temporary file, then layout rewinds the file and reads the data into a buffer. > Are you saying it's safe to do these things in layout, but dangerous to do > them > in gfx? Or are you saying you want to change the plugin API to get rid of the > temporary file entirely? I want a _clean_ implementation which doesn't rely on implemementation details of the Unix plugin API. > > Therefore my suggestion is to put the data of the temp. file into a string > > (or > > if someone complains about performance - mmap() it) and pass the string and > > the > > length to gfx. That will protect Mozilla from any weird actions done by > > plugins > > writing to the |FILE *| (and keeps that code in a central location) and > > passes a string around. > > If everyone thinks mmap() is portable enough to use it here, then fine. If I remember it correctly there is something like |PR_MMap()| in NSPR... and all modern Unix versions supported by Mozilla have |mmap()|. > Otherwise, if the gfx module can handle either format just as easily, or if it > doesn't implement rendering postscript fragments, then you've done this > potentially huge memory allocation (up to 128MB in the current implementation) > and file I/O for nothing. The upper 128MB limit is only a safety clamp to avoid that things go completely out of control. No one said that the actual PostScript data stream from the plugin comes even near that barrier (usually the amount of data are not larger than 1/50 of the current safety clamp) ... :) > The best approach is to leave the data in the form it's produced by the plugin > for as long as possible. That's what my current patch does. The data itself remain untouched, I only change the transport mechanism used to pass the data throught the API layers in Mozilla. > If the printing module needs to convert it somehow, > well, that is its job. Doing a particular data conversion speculatively, just > because some hypothetical future gfx interface might prefer it in that format, > is bad software design. Erm... do you really think that exposing the details how plugin printing works on Unix/Linux is good software design ? Passing the |FILE *|-handle around is BAD software design. It's actually one of the _WORST_ things ever done, similar to the disaster that someone put glib/GTK-functions in gfx/src/x11shared/ where they really do not belong to. > > > > 2. the patch completely misses support for Xprint > > > > > > Well, the PS maintainer provided an initial PS implementation. Who do you > > > believe should provide the xprint implementation? The java, flash, and > > > other > > > plugin maintainers all have their own release cycle to consider, so there > > > is > > > value in finalizing the design whether or not it's fully implemented in > > > mozilla. > > > > Right now plugin printing works with Xprint so the current patch would > > regress > > that functionality and I doubt that a patch is going to be approved by > > anyone > > which introduces new regressions (weired... you have CVS write access and > > don't know the rules or what ?). > > My understanding is that right now, we have an interface which specifies a > mozilla-specific postscript environment, presumably works correctly for > xprint, > doesn't work correctly for ps, and is implemented by just about nothing > available to the public. Just because something isn't OpenSource doesn't mean that Mozilla should not support it. > Are you saying that you want to stick with the current interface, instead of > moving to an EPSF-based interface? I never said I am against the EPSF idea as an intermediate solution. But I'd like to maintain _backwards_-compatibility if possible. I know that most of the Linux people really don't care much about such details but I do and Sun does. You own now the gfx/src/ps/ code and it's your right to decide that you don't want to maintain backwards compatibility, but I own the gfx/src/xprint/ code and I'd like to maintain compatibilty to the "old way" if there is a way to do so. In the long term I think the current Unix/Linux plugin API needs to be enhanched - moving away from the PostScript-centric design and it's limitations (e.g. no alpha channel, etc.). There should be a way to allow that plugins can use OpenGL, Cairo etc for printing, too. Otherwise plugins which can print will be rare since it always means that engineers have to do twice the work: First write rendering code for the video display and then write the same code in PostScript for printing. No wonder that plugins which can print are mainly found in commercial products... ;-/
Robert O'Callahan wrote > FILE* belongs to libc. There is nothing Unix specific about it. The only Unix > specific thing here is that it's on Unix that plugins produce EPS that needs > to be passed to Gfx. Once we've decided to add EPS support to Gfx interfaces, > then as far as "abstraction" and "portability" are concerned, FILE* is as good > as char*.# > (I would not have any problem if we decided to start passing FILE* around > in Mozilla, except that we have our own stream classes that are a bit better, > but the're not suitable here.) ... but the |FILE *|-handle is specific to the Unix plugin API and requires special processing (like rewind etc.). I'd like to keep those details _IN_ the Unix plugin code and _OUT_ of the gfx print modules. Mozilla's PostScript module is the ONLY print API which directly can take advantage of a |FILE *| - all other print APIs like Xprint, Qt etc. take a string as input. And not a file handle. IMHO it's a bad design (additinally to the detail that implementation details of one API layer are exposed to another layer) to design something based on a minority while all other APIs made a different design decision. > > And it processes the PS data multiple times, too - which isn't very > > efficient either > > Who cares? The main thing is that the code be simple and correct. Speed of > printing plugins is never going to be a major performance bottleneck. Sure, but if there is an easy and cheap way to gain more speed that way should be chosen, especially when it also includes a price tag labelled "cleaner design" ... :)))
A more lighthearted comment: We have two choices here: a) Debate |FILE *|-vs.-"String" until the h*ll freezes, hitting our heads permanently against each other OR b) review the current patch and get it in :)
> ... but the |FILE *|-handle is specific to the Unix plugin API and requires > special processing (like rewind etc.). I'd like to keep those details _IN_ the > Unix plugin code and _OUT_ of the gfx print modules. No. What is specific to the Unix plugin API is the requirement to pass Postscript data through for printing. We can pass it in a file or in memory, and if the former makes more sense (as I think it does), then a FILE* is a perfectly reasonable way to do that. It's better to pass the data in a file because a) the data will be read and written sequentially and b) there could be a lot of it which will consume a lot of RAM or at least virtual address space if we must access it as a single contiguous buffer. Note that in Xprint you're copying the data into another buffer anyway, so the simple rewind+read-the-whole-file-into-the-buffer code is going to be tiny and require one less copy of the data than you currently need (potentially saving a lot of memory). So I'm suggesting option c): bite the bullet, use FILE*, or I'll have to stamp superreview-. Also I'd like nsEPSObjectPS/Xp to share the common parsing code, thanks.
roc@ocallahan.org wrote: > > ... but the |FILE *|-handle is specific to the Unix plugin API and requires > > special processing (like rewind etc.). I'd like to keep those details _IN_ > the > > Unix plugin code and _OUT_ of the gfx print modules. > > No. What is specific to the Unix plugin API is the requirement to pass > Postscript data through for printing. We can pass it in a file or in memory, > and > if the former makes more sense (as I think it does), then a FILE* is a > perfectly reasonable way to do that. Again, I disagree. We would duplicate plugin-specific handling code in each print module. And each time we change that we will have to update each module. Each fix - twice the work. > It's better to pass the data in a file > because a) the > data will be read and written sequentially ... which is not correct since the parser will load the data multiple times. > and b) there could be a lot of it > which will consume a lot of RAM or at least virtual address space if we must > access it as a single contiguous buffer. > > Note that in Xprint you're copying the data into another buffer anyway, so the > simple rewind+read-the-whole-file-into-the-buffer code is going to be tiny and > require one less copy of the data than you currently need (potentially saving > a lot of memory). > > So I'm suggesting option c): bite the bullet, use FILE*, or I'll have to stamp > superreview-. I'll suggest to mark this bug as WONTFIX then... =:-) Alternatively we can use mmap() which would be much more efficient than fopen()/fgetc()/fclose() (e.g. char-by-char reading) ... > Also I'd like nsEPSObjectPS/Xp to share the common parsing code, thanks. No, this was intentionally since I have other design plans for the |nsEPSObjectXp| path which cannot be shared with the PostScript version. Nor should the Xprint code depend on any sources in gfx/src/ps/ (that's by design).
> Again, I disagree. We would duplicate plugin-specific handling code in each > print module. And each time we change that we will have to update each module. > Each fix - twice the work. I don't know what you're talking about. Can you give an example? > ... which is not correct since the parser will load the data multiple times. Multiple sequential passes through the data are still sequential. > I'll suggest to mark this bug as WONTFIX then... =:-) If necessary, although more likely I'll just ask Kenneth to fix up your patch (or do it myself) to get it working with Postscript, check that in, and then you can fix Xprint or not as you wish. > Alternatively we can use mmap() which would be much more efficient than > fopen()/fgetc()/fclose() (e.g. char-by-char reading) ... mmap is not suitable for variable-length possibly-very-large sequentially-accessed data streams. And fgetc is for suckers, use fread/fwrite instead. > No, this was intentionally since I have other design plans for the > |nsEPSObjectXp| path which cannot be shared with the PostScript version. The parsing code can still be broken out into a separate file in x11shared and shared.
roc+moz wrote: > > Again, I disagree. We would duplicate plugin-specific handling code in each > > print module. And each time we change that we will have to update each > > module. > > Each fix - twice the work. > > I don't know what you're talking about. Can you give an example? If there is something wrong with the PS stream processing we have to touch both print modules since the matching code would be replicated over both modules. I want to keep the _maintaince_ _requirements_ and _codesize_ low if possible. I'd like to have a clean and simple design. Running around with the |FILE *|-handle and duplicating code will just waste code (sure, there is the EPSF parser, but that fork has at least a reason (to handle PCL drivers in Xprint)). > > ... which is not correct since the parser will load the data multiple times. > > Multiple sequential passes through the data are still sequential. > > > I'll suggest to mark this bug as WONTFIX then... =:-) > > If necessary, ... uhm... did you see the SMILEY above ? :))))) > although more likely I'll just ask Kenneth to fix up your patch > (or do it myself) to get it working with Postscript, check that in, If you checkin just kherron's patch you'll loose all the bugfixing and testing I and Sun did in the meantime. > and then > you can fix Xprint or not as you wish. That would regress existing functionality then... ... but again - take a look at the smiley, please... :))) > > Alternatively we can use mmap() which would be much more efficient than > > fopen()/fgetc()/fclose() (e.g. char-by-char reading) ... > > mmap is not suitable for variable-length possibly-very-large > sequentially-accessed data streams. > And fgetc is for suckers, use fread/fwrite > instead. mmap() is still much faster than fread() (that was at least one of the reasons why Multics introduced that feature) and will simplify the design of the parser a lot. > > No, this was intentionally since I have other design plans for the > > |nsEPSObjectXp| path which cannot be shared with the PostScript version. > > The parsing code can still be broken out into a separate file in x11shared and > shared. 1. Erm, please don't put code into x11shared which shouldn't be "in" there. Long ago there was the debate of a gfx/src/unixshared/ for such purposes but that dir was never approved... ;-(( 2. As I said, I am going to add other functionality there... and then I have to fork the parser code again. Better I do that now than putting that change into a patch which would be otherwise a 20line patch.
> If there is something wrong with the PS stream processing We're talking about the code to rewind a FILE*, see how big it is, and maybe read all its data into a buffer (for Xprint). I don't see how that's going to need much maintenance. Feel free to assign such bugs to me. > If you checkin just kherron's patch As I said, "fix up *your* patch" > mmap() is still much faster than fread() "It depends" and "who cares". > simplify the design of the parser a lot. Maybe a bit. Probably not much. Write the code and we'll see :-) We can put the parsing code in gfx/shared, then. I think you should avoid forking the parser because I can see *this* code as a place that might be fragile and require changes.
If there's a genuine concern about exposing this FILE* as a plugin printing implementation detail, or having multiple copies of the file-handling code, then wouldn't the correct response be to wrap the whole thing in an object? Something like nsEPSObject, but with additional functionality to identify the kind of output that the plugin produced, write the plugin output to a stream, append it to a string, etc. The result could live in gfx/src or somewhere in layout.
I discussed this with roc+moz on IRC and we made a deal: 1. RenderEPS() uses |FILE *|+filesize 2. Print modules do mmap() (using NSPR API or fileno()) 3. |nsEPSObjectXp| remains seperate in the gfx/src/xprint/ code rcowork: Everything correct ?
> |FILE *|+filesize You don't need the filesize. Just use fseek to get the size. Other than that, yeah, I'll sign off on that. kherron: we could encapsulate the data in an object, but for now, I think FILE* will serve us.
Comment on attachment 148414 [details] [diff] [review] New patch for 2004-05-02-trunk Robert O'Callahan wrote: > > |FILE *|+filesize > > You don't need the filesize. Just use fseek to get the size. > > Other than that, yeah, I'll sign off on that. OK. New patch this weekend... I am too tired now... ;-(
Attachment #148414 - Flags: superreview?(roc)
Attachment #148414 - Flags: review?(dantifer.dang)
> > Other than that, yeah, I'll sign off on that. > OK. New patch this weekend... I am too tired now... ;-( I am more than happy that we can have an agreement. to me, to pass FILE * or char * means nothing, it is important to check in this patch as soon as possible...
Target Milestone: mozilla1.8alpha1 → mozilla1.8alpha3
Attachment #148414 - Attachment is obsolete: true
Comment on attachment 153831 [details] [diff] [review] New patch for 2004-07-18-trunk to make roc+moz happy :) Requesting r=/sr= ...
Attachment #153831 - Flags: superreview?(roc)
Attachment #153831 - Flags: review?(petez.bugzilla)
Too many rejects...
(In reply to comment #64) > Too many rejects... ?!
Comment on attachment 153831 [details] [diff] [review] New patch for 2004-07-18-trunk to make roc+moz happy :) Ahh... I got it... the patch is rotten again thanks to other changes in gfx/ ... ;-( New patch follows in a few mins...
Attachment #153831 - Attachment is obsolete: true
Attachment #153831 - Flags: superreview?(roc)
Attachment #153831 - Flags: review?(petez.bugzilla)
Attachment #153952 - Flags: superreview?(roc)
Attachment #153952 - Flags: review?(petez.bugzilla)
+ /* aDirtyRect contains the right information for ps print */ Does it? What is the dirtyrect when printing, anyway? How has this been tested? Do we have a test plugin that outputs EPS? The code duplication here is really ugly. Can the EPSObjects share code in a common base class, please? Also, the preamble that gets emitted by RenderEPS looks the same (and it looks complicated). Why can't that be accessed via a utility function in an EPSObject base class?
> Does it? What is the dirtyrect when printing, anyway? > > How has this been tested? Do we have a test plugin that outputs EPS? Yeah, we have one now. http://bugzilla.mozilla.org/show_bug.cgi?id=238704 > The code duplication here is really ugly. Can the EPSObjects share code in a > common base class, please? Also, the preamble that gets emitted by RenderEPS > looks the same (and it looks complicated). Why can't that be accessed via a > utility function in an EPSObject base class? Perhaps Roland has his own reason. But I also think it will be better to pub EPSObject in seperate files. And what is more, I failed to print plugins for mozilla crashed. I don't know why. Now I am building a clean version to try it again.
compile output: nsRenderingContextPS.o: In function `nsRenderingContextPS::RenderEPS(nsRect const&, _IO_FILE*)': /work/mozilla/print/mozilla/gfx/src/ps/nsRenderingContextPS.cpp:1339: undefined reference to `nsEPSObjectPS::nsEPSObjectPS[in-charge](char const*, unsigned long)' nsPostScriptObj.o: In function `nsPostScriptObj::render_eps(nsRect const&, nsEPSObjectPS&)': /work/mozilla/print/mozilla/gfx/src/ps/nsPostScriptObj.cpp:2809: undefined reference to `nsEPSObjectPS::WriteTo(_IO_FILE*)' crashed error message: dist/bin/mozilla-bin: relocation error: /work/mozilla/print/mozilla/dist/bin/components/libgfxps.so: undefined symbol: _ZN13nsEPSObjectPSC1EPKcm After moving nsRenderingContextPS.cpp in gfx/src/ps/Makefile.in from 'EXPORT' section to CPPSRC section, it works. And no more problems are found.
> > After moving nsRenderingContextPS.cpp in gfx/src/ps/Makefile.in from 'EXPORT' ~~~~~~~~~~~~~~~~~~~~~~~~~ nsEPSObjectPS.cpp > section to CPPSRC section, it works. >
Robert O'Callahan write: > + /* aDirtyRect contains the right information for ps print */ > > Does it? What is the dirtyrect when printing, anyway? > > How has this been tested? Via the sample plugins... > Do we have a test plugin that outputs EPS? Yes, see Dantifers comment > The code duplication here is really ugly. Can the EPSObjects share code in a > common base class, please? Please remember our IRC discussion and comment #58 (part 3). The two classes will evolve seperately in the future (which means: CAIRO support for Xprint) and we won't have time to permamently keep the gfx/src/ps/ code in sync with the gfx/src/xprint/ codebase just becase there is the artificial requirement of a common base class.
ZF.Dang wrote: > compile output: > > nsRenderingContextPS.o: In function `nsRenderingContextPS::RenderEPS(nsRect > const&, _IO_FILE*)': > /work/mozilla/print/mozilla/gfx/src/ps/nsRenderingContextPS.cpp:1339: > undefined > reference to `nsEPSObjectPS::nsEPSObjectPS[in-charge](char const*, unsigned > long)' > nsPostScriptObj.o: In function `nsPostScriptObj::render_eps(nsRect const&, > nsEPSObjectPS&)': > /work/mozilla/print/mozilla/gfx/src/ps/nsPostScriptObj.cpp:2809: undefined > reference to `nsEPSObjectPS::WriteTo(_IO_FILE*)' Which OS+compiler is that ? > crashed error message: > > dist/bin/mozilla-bin: relocation error: > /work/mozilla/print/mozilla/dist/bin/components/libgfxps.so: undefined symbol: > _ZN13nsEPSObjectPSC1EPKcm I don't see this error, neither on Suse 8.2 nor on Solaris... ;-( After moving nsRenderingContextPS.cpp in gfx/src/ps/Makefile.in from 'EXPORT' section to CPPSRC section, it works.
Attachment #153952 - Attachment is obsolete: true
Attachment #153952 - Attachment is obsolete: false
Attachment #153952 - Flags: superreview?(roc)
Attachment #153952 - Flags: review?(petez.bugzilla)
Attachment #158311 - Flags: superreview?(roc)
Attachment #158311 - Flags: review?(petez.bugzilla)
Comment on attachment 158311 [details] [diff] [review] Updated patch for 2004-09-08-trunk r=leon
Attachment #158311 - Flags: review?(petez.bugzilla) → review+
Comment on attachment 158311 [details] [diff] [review] Updated patch for 2004-09-08-trunk This patch is ok.
Attachment #158311 - Flags: approval-aviary+
Comment on attachment 158311 [details] [diff] [review] Updated patch for 2004-09-08-trunk ZF.Dang, please don't set flags that you're not allowed to set. For the record, I'm very much opposed to anything like this landing on 1.7.
Attachment #158311 - Flags: approval-aviary+
Comment on attachment 158311 [details] [diff] [review] Updated patch for 2004-09-08-trunk + nsEPSObjectPS eps(data, datalen); + NS_ENSURE_SUCCESS(eps.GetStatus(), NS_ERROR_INVALID_ARG); you leak the mmapped data if eps.GetStatus() fails. Fix that.
Attachment #158311 - Flags: superreview?(roc) → superreview+
checked in and corrected the problem mentioned in roc's comments
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
Attached patch fix gcc 3.4 build error (obsolete) — Splinter Review
Attached patch better patch to fix bustage (obsolete) — Splinter Review
Attachment #159465 - Attachment is obsolete: true
Attachment #159466 - Attachment is obsolete: true
Comment on attachment 159467 [details] [diff] [review] with larger context sr=dmose
Attachment #159467 - Flags: superreview+
This checkin added documentation on the new printing API plugins are expected to follow, right? If not, could that be added, please?
(In reply to comment #84) > This checkin added documentation on the new printing API plugins are expected to > follow, right? If not, could that be added, please? Where we can add the reference?
filed bug 260525 for Solaris gcc box bustage. Will resolve it ASAP.
jst is the plugin API man IIRC. Maybe he can help us. jst: we've just changed the Unix plugin printing API so that the plugin must generate an EPSF file. The old API was totally broken. We probably should have mentioned it to you first...
> Where we can add the reference? To wherever the plugin printing API is currently documented. I'd like to see this documentation clearly describe what all coordinates involved mean (as well as the fact that the plugin should produce EPSF, of course).
Product: Core → Core Graveyard
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: