Closed
Bug 241607
Opened 21 years ago
Closed 21 years ago
[ps] Separate postscript generation from print job handling
Categories
(Core :: Printing: Output, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: kherron+mozilla, Assigned: kherron+mozilla)
Details
Attachments
(1 file, 1 obsolete file)
91.62 KB,
patch
|
tor
:
review+
roc
:
superreview+
|
Details | Diff | Splinter Review |
In the postscript printing module, the class that generates the postscript is
also responsible for managing temporary output files, setting a printing-related
environment variable, and running the actual print command. The code for
managing the print job is very convoluted, which makes it hard to contemplate
adding new features, such as interfacing with CUPS or just intelligently
constructing an lpr command.
Assignee | ||
Comment 1•21 years ago
|
||
This removes all of the code for temporary files, environment variables, and
running commands from nsPostScriptObj into a separate set of classes for
managing print jobs. I've defined an abstract class, nsIPrintJobPS, along with
separate classes for printing to files, pipes on unix, and via system() on VMS.
This should be more extensible than the current code.
A factory class initializes selects the right kind of print job object based on
the print job spec; the print job object in turn initializes the postscript
object. This is intended to handle cases such as duplex printing, where some
print job classes can handle it themselves but others would tell the PS object
to handle it.
There are some minor changes to mozilla's behavior. First of all, postscript
output is always written to a pair of temporary files and then combined at the
end of the print job; in the past, print-to-file jobs created the final output
file instead of one of the temp files. The new behavior avoids triggering bug
226600. Also, the new implementation will try to remove the MOZ_PRINTER_NAME
environment variable from the environment, or else set it to an empty string,
after each print job.
In nsPostScriptObj I've renamed the two fields that stored the temporary file
handles; this lead to a lot of trivial changes to a lot of fprintf()
statements. I've tried to avoid a lot of unnecessary changes here, but I did
change a few of these to fputs() or fputc() calls, and removed some trivial
white space from the postscript output.
Assignee | ||
Updated•21 years ago
|
Attachment #146953 -
Flags: review?(tor)
Why have a nsIPrintJobPS? Do you intend for classes other than
nsPrintJobsPS to inherit it?
Along a somewhat similar lines, why seperate nsPrintJobPS and
nsPrintJobFilePS?
Why is the print job generated into two temporary files instead
of just one?
The file combiner uses 8192 bytes of stack space, which although
we regularly have >50 deep stacks, seems a bit excessive.
Assignee | ||
Comment 3•21 years ago
|
||
(In reply to comment #2)
> Why have a nsIPrintJobPS? Do you intend for classes other than
> nsPrintJobsPS to inherit it?
I wanted a base class with no implementation details in it. nsPrintJobPS
contains a particular implementation of temporary files. At some point we could
in theory have a print job implementation that has no use for this particular
temp-file implementation. But yes, I expect that in the near term, any new print
job classes will inherit from nsPrintJobPS.
> Along a somewhat similar lines, why seperate nsPrintJobPS and
> nsPrintJobFilePS?
A class that prints through lpr using a dynamically generated lpr command line
has no use for the Destination stuff added to nsPrintJobFilePS. Nor does a class
that prints through the CUPS API <http://cups.org/spm.html>. One of my goals for
this patch is to develop a framework for adding new features.
> Why is the print job generated into two temporary files instead
> of just one?
Postscript document structuring conventions. Procedures, arrays, fonts, etc.
defined in the document are normally placed at the beginning of the document
instead of being mixed in with the page content. This lets the user use tools to
reorder pages, remove pages from the print job, and the like without running the
risk of removing something that's needed elsewhere in the document.
In mozilla's case, the freetype code can embed fonts into the print job. It
doesn't know which fonts to embed until all of the page content is processed,
and the font data needs to go toward the top of the file. So the prolog,
including the font data, is written to one file, while the page-drawing commands
are written to a second file. Mozilla has worked this way ever since the
freetype stuff was added.
Assignee | ||
Comment 4•21 years ago
|
||
(In reply to comment #3)
> I wanted a base class with no implementation details in it. nsPrintJobPS
> contains a particular implementation of temporary files. At some point we could
> in theory have a print job implementation that has no use for this particular
> temp-file implementation. But yes, I expect that in the near term, any new print
> job classes will inherit from nsPrintJobPS.
Actually, I take this back. To fully address bug 226600, I've been thinking
about a stub print job class for print-preview operations. Such a class wouldn't
have any use for the temporary-file implementation in nsPrintJobPS, so it would
probably inherit directly from nsIPrintJobPS.
In fact, at one point I considered submitting this refactoring plus the
print-preview job class as the fix for bug 226600, but I eventually decided it
would be better to introduce the new class hierarchy separate from any bug fixes.
Comment on attachment 146953 [details] [diff] [review]
Refactor print job handling into a separate class
I'll leave the call on the stack usage for the sr. r=tor
Attachment #146953 -
Flags: review?(tor) → review+
Assignee | ||
Comment 6•21 years ago
|
||
Comment on attachment 146953 [details] [diff] [review]
Refactor print job handling into a separate class
Dbaron, you were involved with earlier patches dealing with temp files and
environment variables. Could you sr this?
Attachment #146953 -
Flags: superreview?(dbaron)
Assignee | ||
Updated•21 years ago
|
Attachment #146953 -
Flags: superreview?(dbaron) → superreview?(roc)
Roland, any comments before I approve this?
I guess my question is, should this print job support be specific to Postscript
or can we reuse it? Would we want to reuse it in a Cairo printing backend, for
example, so we don't have to implement CUPS-PS and CUPS-Cairo?
Assignee | ||
Comment 9•21 years ago
|
||
(In reply to comment #8)
> I guess my question is, should this print job support be specific to Postscript
> or can we reuse it? Would we want to reuse it in a Cairo printing backend, for
> example, so we don't have to implement CUPS-PS and CUPS-Cairo?
My goal with this patch was to enable more sophisticated printjob support, but
it also moves us toward being able to replace the current postscript renderer or
supporting multiple renderers. I don't have specific plans, but I've done a
little research on developing a PDF or DVI renderer, and I try to keep this kind
of thing in mind.
I hadn't heard of cairo before now, but it seems the cairo PS renderer just
writes to a FILE*, so it should interface well with this print job object.
However, a full cairo-based printing system is still pretty far off.
Comment 10•21 years ago
|
||
Robert O'Callahan wrote:
> I guess my question is, should this print job support be specific to
> Postscript or can we reuse it?
With the current design of the patch the print job handling cannot be reused by
other print modules, the job handling would be bound to the PostScript module
exclusively.
> Would we want to reuse it in a Cairo printing
> backend,
There should be no "Cairo" printing _backend_ - that code should be implemented
in a way (for example like the POstScript plugin print code on Unix/Linux) that
it can be reused by gfx/src/ps/, gfx/src/gnomeprint and gfx/src/xprint/.
Hardcoding that only to the gfx/src/ps/ module isn't a great idea now that
multiple platforms have dropped support for it.
> for example, so we don't have to implement CUPS-PS and CUPS-Cairo?
Erm... please stop thinking about "CUPS". "CUPS" is _NOT_ the only print spooler
system on Linux (think about LPRng etc.) nor on Unix (where many have their own
spooler implementations).
Instead of a CUPS-centric spooler implementation there should be something which
works crossplatform.
Comment 11•21 years ago
|
||
Kenneth Herron wrote:
> (In reply to comment #8)
> > I guess my question is, should this print job support be specific to
> > Postscript
> > or can we reuse it? Would we want to reuse it in a Cairo printing backend,
> > for
> > example, so we don't have to implement CUPS-PS and CUPS-Cairo?
>
> My goal with this patch was to enable more sophisticated printjob support, but
> it also moves us toward being able to replace the current postscript renderer
> or supporting multiple renderers.
Erm... multiple renderers for different renderers should be handled in
gfx/src/gtk/nsDeviceContextSpec.cpp, NOT in the PostScript code - and stuff like
Cairo should be implemented more like the plugin printing code to avoid that it
gets hardcoded to one print module.
> I don't have specific plans, but I've done a
> little research on developing a PDF or DVI renderer, and I try to keep this
> kind of thing in mind.
A new renderer should live in a new dir (e.g. gfx/src/dvi/ or gfx/src/pdf/;
however PDF output is already handled by the Xprint module) and should be
completely independed from the PostScript module codebase.
> I hadn't heard of cairo before now, but it seems the cairo PS renderer just
> writes to a FILE*, so it should interface well with this print job object.
No, that should not be designed like that. The Cairo stuff should be added in a
way that multiple print backends can use it, including that both OpenGL output
(for Xprint since the Xprt server now has OpenGL support) and PostScript output
work for printing. The Unix/Linux plugin printing code could be used as basis.
I think it would be fairly easy, and useful, to separate the file/pipe/command
stuff from the actual two-temp-file postscript generation. The former could live
in gfx/src/x11shared, and eventually handle spoolers such as CUPS, and also
handle data coming from gfx/cairo or other sources (by exposing a FILE* that
anyone can write to, the same FILE* you currently pass to Assemble). The latter
would continue in gfx/ps.
Kenneth, does that make sense?
Assignee | ||
Comment 13•21 years ago
|
||
In my copious free time I've been looking at how to separate the print job code
from PS and I've run across a snag regarding how to initialize the print job
object. Right now it initializes itself from an nsDeviceContextSpecPS which is
obviously PS-specific.
nsIDeviceContextSpec is a COM interface. The base interface doesn't define any
useful methods. There are two full implementations, one for gtk and one for
xlib, plus independent PS and xprint interfaces which basically define the
getters that each module needs. All of these interfaces are part of their
respective modules so there's no obvious interface for an independent class to use.
So initializing the print job object seems to require creating something like
nsDeviceContextSpecPrintJob, or else moving the printjob initialization logic
out of this class and into something (probably the print job factory) which
would have to remain in the PS module (and be replicated for other users of the
print job object).
Another possibility might be to merge all of the DeviceContextSpec classes into
a single class which wouldn't be tied to any particular gfx module. The GTK and
Xlib implementations are literally identical but for their class names; bug
130857 is about merging them into one class, but it's held up for some reason.
If we had a single DeviceContextSpec class it may be possible to dispose of the
PS and xprint classes as well, though there may be issues here that I'm not
aware of.
Comment on attachment 146953 [details] [diff] [review]
Refactor print job handling into a separate class
Alright. If it's nontrivial to separate them, let's not bother for now. we can
refactor it later. Just check it in.
+nsPrintJobPS::Assemble(FILE *aDestination = nsnull)
Why the default nsnull? That doesn't seem to be useful.
Attachment #146953 -
Flags: superreview?(roc) → superreview+
Assignee | ||
Comment 15•21 years ago
|
||
(In reply to comment #14)
> (From update of attachment 146953 [details] [diff] [review])
> Alright. If it's nontrivial to separate them, let's not bother for now. we can
> refactor it later. Just check it in.
Er, whoops. Actually, while reviewing roc's suggestion I realized we probably
don't need two temporary files after all, because we can defer generating the
prolog until after the body of the postscript document is finished, and just
write the prolog directly into the final output stream.
This is a substantial change from what's in the patch, so I think it's better to
just write a new patch and go through another round of review.
> +nsPrintJobPS::Assemble(FILE *aDestination = nsnull)
>
> Why the default nsnull? That doesn't seem to be useful.
>
Assignee | ||
Comment 16•21 years ago
|
||
This is a simpler version of the previous patch. The printjob object doesn't
own the postscript object and it doesn't supply temporary files; it just
provides a file handle for the postscript object to write the document into.
The postscript object now uses only one temporary file, used for the document
body; it defers creating the document header until the end of the process when
it can write directly into the submission file handle.
There's a printjob class for print preview which is never instantiated. The
device context spec class needs some additional work to support this properly;
see bug 226600 comment 5. I'd like to do that separately from this patch.
Attachment #146953 -
Attachment is obsolete: true
Assignee | ||
Updated•21 years ago
|
Attachment #149117 -
Flags: superreview?(roc)
Attachment #149117 -
Flags: review?(tor)
Comment on attachment 149117 [details] [diff] [review]
Simpler patch
+#include "nsType8.h"
Shouldn't this be #ifdef MOZ_ENABLE_FREETYPE2?
+ if (mPSObj)
delete mPSObj;
could be just 'delete mPSObj;'
+ if (mPrintJob)
+ delete mPrintJob;
similar
+ NS_PRECONDITION(submitFP, "No print job submission handle");
should be NS_ASSERTION
+ fprintf(f, "%s",
why not fputs? Actually I don't understand why you're breaking up these
fprintfs...
other than that, looks great
Attachment #149117 -
Flags: superreview?(roc) → superreview+
Assignee | ||
Comment 18•21 years ago
|
||
> + fprintf(f, "%s",
> why not fputs? Actually I don't understand why you're breaking up these
> fprintfs...
I apologize; I should have explained that. It's an attempt to address bug 223213
by splitting up a long string constant into a handful of shorter ones. The
reason for using fprintf() is that I think it's slightly easier to read than the
fputs version:
fputs(
"..."
[many lines]
"...", fp)
The performance difference between |fprintf(f, "%s", string)| and |fputs(string,
f)| is trivial.
This part of the patch isn't very important to me. Bug 223213 is trivial from a
practical standpoint, so I always planned to fix it at some convenient time. I
could remove or change it to fputs() if you'd prefer.
Status: NEW → ASSIGNED
Sounds reasonable. Leave them as fprintfs then.
Comment 20•21 years ago
|
||
Comment on attachment 149117 [details] [diff] [review]
Simpler patch
Sorry about the delay - r=tor.
Attachment #149117 -
Flags: review?(tor) → review+
Assignee | ||
Comment 21•21 years ago
|
||
Checked in:
Checking in Makefile.in;
/cvsroot/mozilla/gfx/src/ps/Makefile.in,v <-- Makefile.in
new revision: 1.52; previous revision: 1.51
done
Checking in nsDeviceContextPS.cpp;
/cvsroot/mozilla/gfx/src/ps/nsDeviceContextPS.cpp,v <-- nsDeviceContextPS.cpp
new revision: 1.67; previous revision: 1.66
done
Checking in nsDeviceContextPS.h;
/cvsroot/mozilla/gfx/src/ps/nsDeviceContextPS.h,v <-- nsDeviceContextPS.h
new revision: 1.38; previous revision: 1.37
done
RCS file: /cvsroot/mozilla/gfx/src/ps/nsIPrintJobPS.h,v
done
Checking in nsIPrintJobPS.h;
/cvsroot/mozilla/gfx/src/ps/nsIPrintJobPS.h,v <-- nsIPrintJobPS.h
initial revision: 1.1
done
Checking in nsPostScriptObj.cpp;
/cvsroot/mozilla/gfx/src/ps/nsPostScriptObj.cpp,v <-- nsPostScriptObj.cpp
new revision: 1.114; previous revision: 1.113
done
Checking in nsPostScriptObj.h;
/cvsroot/mozilla/gfx/src/ps/nsPostScriptObj.h,v <-- nsPostScriptObj.h
new revision: 1.44; previous revision: 1.43
done
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobFactoryPS.cpp,v
done
Checking in nsPrintJobFactoryPS.cpp;
/cvsroot/mozilla/gfx/src/ps/nsPrintJobFactoryPS.cpp,v <-- nsPrintJobFactoryPS.cpp
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobFactoryPS.h,v
done
Checking in nsPrintJobFactoryPS.h;
/cvsroot/mozilla/gfx/src/ps/nsPrintJobFactoryPS.h,v <-- nsPrintJobFactoryPS.h
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.cpp,v
done
Checking in nsPrintJobPS.cpp;
/cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.cpp,v <-- nsPrintJobPS.cpp
initial revision: 1.1
done
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.h,v
done
Checking in nsPrintJobPS.h;
/cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.h,v <-- nsPrintJobPS.h
initial revision: 1.1
done
Checking in nsRenderingContextPS.cpp;
/cvsroot/mozilla/gfx/src/ps/nsRenderingContextPS.cpp,v <-- nsRenderingContextPS.cpp
new revision: 1.76; previous revision: 1.75
done
Assignee | ||
Comment 22•21 years ago
|
||
I overlooked the |#ifdef MOZ_ENABLE_FREETYPE2| correction on the first checkin,
but it's in now. Resolving FIXED.
Status: ASSIGNED → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•