Closed Bug 234182 Opened 21 years ago Closed 19 years ago

[PS] freetype printing : replace a type 9 font with multiple type 1 fonts (to support PS level 1/2 printers)

Categories

(Core :: Printing: Output, enhancement)

x86
Linux
enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla1.8beta2

People

(Reporter: jshin1987, Assigned: jshin1987)

References

Details

(Keywords: intl)

Attachments

(3 files, 7 obsolete files)

Currently, FT2 printing module converts truetype outlines to postscript outlines
and wrap them up in a type 9 font (Mozilla source tree calls it type8 font, but
Adobe's PS reference manual 3/e calls it type 9 font) which uses CMap to map
characters to glyph indices (as is done in CID-keyed fonts). To print PS output
files made that way, we need to use either a PS level 3 device or downgrade them
to PS level 2 or level 1 with ghostscript (pswrite device). It has worked rahter
well for me, but apparently it doesn't always work well for others with
different PS printers.

Although a lot of home users don't have a PS printer so that they have to filter
with ghostscript, a significant number of people use PS printers at work and
school.  It's not so desirable for them to  downgrade to PS level 2/1 ONLY to
get  a lower quality print output. I found that ghostscript 8.0x source has the
followinng to say about the current status of 'pswrite' device. 


   We  would like to improve the high-level PostScript-writing pswrite driver to
bring it up to parity with the PDF-writing driver (including the many
improvements in the latter  being  implemented  in Ghostscript 7.xx).
Specifically, we want it to write text  as  text  rather  than  bitmaps,  and 
to  consistently write images in their original high-level form. We have already
started to factor out code that should be common to these two drivers,
specifically for writing embedded fonts and compressed data streams.

I printed a couple of documents to PS files with openoffice and found that
they convert truetype outlines to postscript outlines (just like Mozilla
does), but it wraps up  glyphs (up to 64k glyphs in a truetype font)
in multiple  type 1 fonts (instead of wrapping them up in a single type
9 font). Therefore, PS files generated by open office can be printed out 
with any PS printer without any downgrading / filtering. 

I guess type9 was chosen because FT2 printing code is a lot simpler that
way than otherwise. With type 9, Mozilla's printing code doesn't have to
worry about mapping characters (Unicode code points) to glyph indices
because that's taken care of by CMap table spit out at the beginning
of a PS output. With type1, we have to keep the map from characters to
(font fragment index, glyph index) for all fonts and switch between
multiple type1 fonts corresponding to a single truetype font. 


P.S.  BTW, I also found a usenet posting, according to which pswrite in gs
7.x uses type3 font (apparently with outlines converted to bitmaps)
while gs 8.x doesn't. Therefore, gs 8.x pswrite device may do a better job with
embedded fonts than that in gs 7.x
FWIW, a type1 font may contain any number of character glyphs. The encoding
vector is limited to 256 entries, but that only affects the "show" operator (and
similar operators). All of the glyphs are accessible by name through the level 2
"glyphshow" operator, without regard to the encoding vector.

The base PS module basically prints unicode as follows, ignoring the hooks for
user-defined additional fonts:

1) Read the next 16-bit character code from the input stream
2) Look up the code in a hash table to obtain the glyph name, or else print the
".notdef" character.
3) Call glyphshow with the glyph name to print the glyph. glyphshow prints the
".notdef" glyph if the named glyph isn't present in the current font.

In principle this would work for fonts containing very large numbers of glyphs,
as long as all of the needed glyph names were in the hash table. In practice, of
course, this is a rather hokey way to print, and there are certainly ways to
improve on it. But the point is that you could construct a single font
containing all of the glyphs and then print using something close to the current
printing logic.
Summary: freetype printing : replace a type 9 font with multiple type 1 fonts → freetype printing : replace a type 9 font with multiple type 1 fonts
Kenneth Herron wrote:
> FWIW, a type1 font may contain any number of character glyphs.

Erm... you cannot simply start uploading all glyphs in one print job. This works
for GhostScript but NOT for real printers since they have limited memory.
Remember that some Asian fonts have few ten thousand glyphs per font - which
will kill almost every small printer if you download all glyphs in one step.
BTW: There is already such a bug in bugzilla where lexmark postscript printers
run out of memory in larger print jobs. Using PS Type1 fonts instead of PS Type9
may even make the situation much worse.
Additionally the number of outlines per PS Type1 font is limited - you will need
a outline optimizer to work around the problem or you will trigger again printer
firmware crashes when glyphs have many many outlines (Sun's GB18030 TTF font is
one example where this may happen even with HP's newest printer models...
actually this isn't really a bug since the PS spec is violated... still.. the
firmware shouldn't crash.).

> The encoding
> vector is limited to 256 entries, but that only affects the "show" operator 
> (and similar operators). All of the glyphs are accessible by name through the
> level 2 "glyphshow" operator, without regard to the encoding vector.

What about PS Level 1 compatibility ?
Summary: freetype printing : replace a type 9 font with multiple type 1 fonts → [PS] freetype printing : replace a type 9 font with multiple type 1 fonts
Summary: [PS] freetype printing : replace a type 9 font with multiple type 1 fonts → [PS] freetype printing : replace a type 9 font with multiple type 1 fonts (to support PS level 1/2 printers)
*** Bug 219682 has been marked as a duplicate of this bug. ***
(In reply to comment #2)

> > The encoding
> > vector is limited to 256 entries, but that only affects the "show" operator 
> > (and similar operators). All of the glyphs are accessible by name through the
> > level 2 "glyphshow" operator, without regard to the encoding vector.
> 
> What about PS Level 1 compatibility ?

  Aside from other problems mentioned by you, using 'glyphshow' is not such a
good idea as Kenneth implied by 'hokey' (so he can't have been serious..)
OpenOffice does it (breaking a big truetype font into multiple fonts and
wrapping them as type1 fonts) well so that we must be able to do that here, too.
I'm wondering if  I can  'steal' some of  their code.  
Now that I have a better grasp of the way PS-printing code and font subsetting
work, I hope I'll be able to fix this sometime later this month when I have more
free time.
Status: NEW → ASSIGNED
Attached patch 1st attempt (not working) (obsolete) — Splinter Review
It turned out that dividing a single font into multiple fragments is not that
hard. (the way it's done in the current code is not so pretty, but it works).

Generating a valid type 1 font is alot harder than I thought. I have to
calculate values for a few mandatory fields in 'Private Dictionary' of T1 font.
In addition, I have yet to apply a second encryption over 'Private dictionary'
and 'CharStrings'. 

It seems like 'type 1 outline' part of CID-keyed font doesn't have these
additional requirements, which may be one of reasons why bstel went with
CID-keyed fonts.
I gave up generating valid type 1 fonts. Instead, I made a patch that generates
type 3 fonts. Freetype2 currently doesn't let me access subglyphs of composite
fonts so that I can't take advantage of composite glyphs (used in some CJK
fonts, especially Korean fonts) to reduce the output file size. I'm gonna upload
a patch in a moment.

Summary: [PS] freetype printing : replace a type 9 font with multiple type 1 fonts (to support PS level 1/2 printers) → [PS] freetype printing : replace a type 9 font with multiple type 3 fonts (to support PS level 1/2 printers)
Attached patch patch (type 3) (obsolete) — Splinter Review
I haven't yet tested this with real PS printers. ghostscript renders output PS
fles  well. I'll test wiith a PS level 2 device.
 
The output PS size is about 6MB for a Korean page with 3 different fonts and
about 1000 different characters for each font. This is what we have to pay for
using type 3 instead of type 1.[1] For a typical Western European web page, the
sze should be more like hundreds of kBs. 

BTW, I haven't	built a 'gtk1+ft2' build with this patch. The only build I made
was 'gtk2 + Xft'. If you want to build a gtk1+ft2 build and you have freetype
2.1.8 or later, you also have to apply attachment 162272 [details] [diff] [review] for bug 234035. (there
may be a couple of rejects, but they should be easy enough to hand-fix)
 


[1] In case of Korean fonts with composite glyphs, I could have cut down the
file size by two thirds if the FT2 API for outline decomposition lets me access
subglyphs instead of recursively decomposing them all.
Attachment #156150 - Attachment is obsolete: true
Wolfgang, can you test this patch with PS level 1 devices if you can access them?
Target Milestone: --- → mozilla1.8beta2
The current mozlla trunk code produces a PS output of about 1MB while
Konqureror generates a PS output of 2MB. With attachment 174040 [details] [diff] [review], it's about
6MB. The difference between Qt (that also uses type3) and moziilla with my
patch is that the former factors out subglyph outlines and refers to them
instead of 'inlining' them for every character that uses them. Qt also uses
composite fonts, but that doesn't make a big difference. For fonts that don't
have composite glyphs, Qt and Mozilla with my patch should produce PS files of
a similar size.
(In reply to comment #8)
> I haven't yet tested this with real PS printers. ghostscript renders output PS
> fles  well. I'll test wiith a PS level 2 device.

Perhaps the following may be of interest for your tests:

You can convert Ghostscript to act as a PostScript level 1 only
interpreter (i.e. Ghostscript forgets all level 2 and 3 functionality).

The following PostScript command switches Ghostscript
into a level 1 interpreter:

1 .setlanguagelevel

Specify this in the Ghostscript command line before the
real PostScript input comes.

For example make a file set-gs-level1.ps
------------------------------------------------------
%!
1 .setlanguagelevel
------------------------------------------------------
and use it in a command like

gs set-gs-level1.ps your-file.ps

to verify whether or not your-file.ps is level 1 compliant.

Unfortunately as far as I know you cannot make a level 2 only
interpreter with a command like

2 .setlanguagelevel

Perhaps Ghostscript version 8.x may have this feature - but
all what I know up to now is only the level 1 stuff.
Thanks. I've just tested it and it blew up apparently not because it uses any PS
L2 features but because there are too many PS intructions for one of glyphs. One
of glyphs has 1300 PS instructions (moveto, lineto,curveto, closepath).
Qt-generated PS file didn't work, either (/dictfull error)

I've just tried open office 1.x(?) and found that it generates type42 (with
sfnts) fonts. (type42 was ruled out in 2001(?) by Brian for the reason I forgot.)

 The output PS file is about 2MB long and doesn't pass PS level 1 test, either.
(the error I got was 'dictfull'). No matter what we do, it may not be possible
to generate a PS output with embedded CJK glyphs for very complex characters
that can be printed out with old level 1 devices unless we can come up with a
outline optimizer (mentioned by Roland) that can do the magic [1]. For most, if
not all, European text and typical CJK text (traditional Chinese text could be
problematic. Attachment 174046 [details] has some Korean syllables that are very rare in 
typical Korean text), I guess we're all right even if the target is  a level 1
device. 

[1] Embedding pre-rendered bitmap at a specific resolution is another matter.

  
Attached patch patch generating type 1 fonts (obsolete) — Splinter Review
After a lot of tinkering, I came to conclude that type 3 fonts are not suitable
for fonts with complex outlines (serif-style TC and Korean fonts) because not
many printers would be able to deal with them. Then, I read the type 1 spec
again and found that I was almost there last fall. With a few changes added to
my last type 1 patch, I came up with this patch. It doesn't do eexec encryption
(which is optional) and the file size is about 4 times smaller than what I got
with type 3 patch. (Had I added eexec encryption, it'd be only 2 times
smaller).

I was able to print TC pages with a serif-style font and my test
page(attachment 174046 [details]) with my PS level 3 printer wiith 16MB memory. I'll try
a PS level 2 device later. Btw, PS files generated by mozilla with my patch
also passed the test with gs emulating a PS level 1 device.
Attachment #174040 - Attachment is obsolete: true
(In reply to comment #14)

> Had I added eexec encryption, it'd be only 2 times smaller).

I was wrong to say the above. eexec encryption itself doesn't change the file
size unless the hexadecimal ASCII form is used instead of the binary output. I
can easily add eexec encryption, but there's no point of doing it because it's
more work for both mozilla (which has to apply the encryption) and PS
interpreters (which have to decrypt). 'Private' dictionary in mozilla's PS
output has nothing 'private' to hide (it's just basic stuff taken off from the
type 1 spec.) and glyph outlines are already encrypted (wth charstring
encryption). The only case for the eexec encryption is that we can generate
ASCII PS files with that (the size being twice as large), which might be
necessary in some cases. I wonder if there's any PS evice and communication
channel that can't deal with binary PS files. 

I'll clean up attachment 174269 [details] [diff] [review] and ask for review later.

A serial line can't be used for transmitting binary PS files, but how widely is
it used? I can add a pref. entry for '7/8bit clean' PS output if it's really a
concern. The default would be 'binary' PS files with no eexec encryption.
Perhaps, that should be a separate bug if there's indeed a demand. 

I got a stream of garbage papers when I sent one of the PS outputs to a HP LJ
over Jet direct. It turned out that binary PS can cause a lot of troubles. For
instance, most HP LJ printers can't cope with binary PS sent over JetDirect
unless it's sitting on top of Appletalk. [1]  USB printers would not work either. 

So, I guess I have to apply eexec encryption and turn the result to hexadecimal
ASCII.

[1] http://wacondatrader.com/pipermail/creator/2004-September/000301.html
http://h20000.www2.hp.com/bizsupport/TechSupport/Document.jsp?objectID=bpj05969
(In reply to comment #15)
> I wonder if there's any PS evice and communication
> channel that can't deal with binary PS files. 

In documents from Adobe it is recommended to use hexadecimal (ASCII)
to be independent of the channel.

For example see the description of the "eexec" operator
in the Adobe "PostScript Language Reference"
and see for example
http://partners.adobe.com/public/developer/en/ps/sdk/5115.Filters.pdf
"2.2 Analysis of Transmission Filters"
It's easy to apply eexec encryption and produce hexadecimal ASCII output. I
cleaned up the code quite a bit and added some comments (although not very
extensive). 

The output file size for attachment 174046 [details] is about twice as big as before
(1.7MB -> 3.4MB) because attachment 174046 [details] has no image and glyph data accounts
for more than 95% of the output file size. For pages with images and a smaller
number of distinct characters, the increase in the file size wouldn't be that
dramatic.  

A PS level 2 printer (HP LJ 4005) with 24MB memory can handle all my test cases
(attachment 174046 [details], http://www.lemonde.fr, http://www.spiegel.de,
http://tw.yahoo.com, http://cn.yahoo.com, http://www.hani.co.kr). 

I'll upload a few PS output files so that somebody with a PS level 1 printer
(with a small amount of memory) can test. BTW, PS output files for lemonde,
spiegel, CN Yahoo, TW Yahoo and hani.co.kr don't pass the level 1 emulation
test. The error is NOT in my synthesized type 1 fonts BUT in a part of PS
output I didn't touch. Even PS outputs generated with the freetype printing
turned off (i.e. generated only using a very old mozilla PS printing module)
don't pass the test.   My text-only test case (attachment 174046 [details]) doesn't have
this problem.
Attachment #174269 - Attachment is obsolete: true
I put up the tar'd and bzip2'd collection of 6 PS output files at
http://i18nl10n.com/mozilla/234182.test_set.tar.bz2 (it's over 4MB). Except for
test2.*ps, 5 PS files didn't pass the PS level 1 emulation test for the reason
mentioned in the previous comment. Anyway, it'd be nice to get some test results
from those with PS printers of different 'vintages'.
Now, I'm back to using type 1 fonts. 
Summary: [PS] freetype printing : replace a type 9 font with multiple type 3 fonts (to support PS level 1/2 printers) → [PS] freetype printing : replace a type 9 font with multiple type 1 fonts (to support PS level 1/2 printers)
Blocks: 282418
I added some comments and cleaned up the code a bit more. I also corrected my
mistake of emitting 1024 ASCII 0's instead of 512 of 'em after the eexec
encrypted section of a type 1 font definition. 

I haven't heard any test result with PS level 1 printers, but I'm pretty sure
this works for them (at least for typical European pages). Moreover, being able
to print out with a PS level 2 printer alone is great. As I wrote in comment
#0, pswriter in gs 7.x doesn't work very well and that was my motivation behind
working on this patch because I had to use one of them. Perhaps, gs 8.x does a
lot better job, but still a lot of people use gs 7.x and some people -
justifiably-  don't want to/cannot get their print jobs through gs.

There are some optimizations to do. In addition, I need to support non-BMP
characters (I've already filed a bug on the issue), but as the first step, this
should be a good start. 

Btw, I put up another test output at
http://i18nl10n.com/mozilla/utf8sample.p10.ps.bz2
(it's the PS file generated by printing to a file
'http://www.columbia.edu/kermit/utf8.html')
Attachment #174303 - Attachment is obsolete: true
Attachment #174483 - Flags: superreview?(dbaron)
Attachment #174483 - Flags: review?(Ervin.Yan)
Comment on attachment 174483 [details] [diff] [review]
patch with a bit more clean-up and additional comments

For reviewers, this patch is large, but a large part of it is putting the
postscript prolog for the old PS printing module inside |if (!mFTPenable)|
block  (we don't need it when FT2 printing is enabled). 

In addition, nsType8.(cpp|h) and nsCidMap.(h|cpp) will be removed.
By returning early from |write_prolog| in nsPostscriptObj.cpp when FT2 printing
is enabled, I could cut down the patch size by 60kB. There no change in the PS
output, but it	makes the review easier. It's also good for 'code archaelogy'
(I wouldn't be	lxr-blamed for the code I didn't write simply because I moved
it and changed the indentation.)
Attachment #174483 - Attachment is obsolete: true
Attachment #174651 - Flags: superreview?(dbaron)
Attachment #174651 - Flags: review?(Ervin.Yan)
Attachment #174483 - Flags: superreview?(dbaron)
Attachment #174483 - Flags: review?(Ervin.Yan)
Comment on attachment 174651 [details] [diff] [review]
same patch but a lot smaller than the previous one

jshin: I test this patch on Linux, it works for my test cases:
1. printing web with GB18030 full characters.
2. http://www.bbc.co.uk/hindi  
3. http://www.bbc.co.uk/thai
4. http://www.yahoo.co.jp
5. http://news.sina.com.cn


just some comments:

1. can not pass compiling with: "--disable-xft --enable-freetype2"

but no problems for "--enable-xft --disable-freetype2" and "--disable-xft
--disable-freetype2"

2. for function FT2ToType1FontName(), font family_name and style_name is used
to composite the Type1 font name.

I think we can use the font PS name as the Type1 font name, because some
Japenese fonts have same family name and style name. see bug 269039 (japanese
printing page shown garbages on Solaris)
Attachment #174651 - Flags: review?(Ervin.Yan) → review+
Thanks for reivew and testing. I fixed the build problem with 'enable-freetype'
(I need to test it on a machine with FT2 2.1.7 or earlier due to bug 234035). 
As for the Sun font naming problem, I'll deal with it in bug 269039 after
landing this.
Attachment #174651 - Attachment is obsolete: true
Attachment #174772 - Flags: superreview?(bzbarsky)
Attachment #174772 - Flags: review+
Attachment #174651 - Flags: superreview?(dbaron)
I'd really like Kenneth to take a look at this patch too...  I'm not going to
have time to do a thorough review anytime soon, but I can do an sr assuming
Kenneth oks the patch sometime this week....
Comment on attachment 174772 [details] [diff] [review]
same patch with the 'enable-freetype2'  build issue addressed

> nscoord
> nsFontPSXft::DrawString(nsRenderingContextPS* aContext,
>                              nscoord aX, nscoord aY,
>                              const char* aString, PRUint32 aLength)
> {
>   NS_ENSURE_TRUE(aContext, 0);
>+  nsAutoBuffer<PRUnichar, WIDEN_8_TO_16_BUF_SIZE> u16Str;

I'm not a fan.	See bug 282814.

>+  if (!u16Str.EnsureElemCapacity(aLength))
>+    return 0; 
>+
>+  PRUnichar *u16Ptr = u16Str.get();
>+
>+  PRUint32 i;
>+  for (i = 0; i < aLength; ++i)
>+    u16Ptr[i] = PRUnichar(PRUint8(aString[i]));
>+

Why not just use NS_ConvertASCIItoUTF16(aString, aLength)?
Also, you may as well put the DrawString(char*) implementation on nsFontPS so it
can be shared, since it looks the same.  The same for GetWidth.
(In reply to comment #29)
> Also, you may as well put the DrawString(char*) implementation on nsFontPS so it
> can be shared, since it looks the same.  The same for GetWidth.

No, I can't unless I get rid of nsFontPSAFM when MOZ_ENABLE_FREETYPE2 |
MOZ_ENABLE_XFT is set, which I may as well do. [1] Note that putting
DrawString(char*) in nsFontPS doesn't reduce the code size (because only one of
nsFontPSXft and nsFontPSFreetype is compiled in). However, it eases the
maintenance. Using NS_ConvertASCIItoUTF16 makes it very simple so that there's
little point.

> Why not just use NS_ConvertASCIItoUTF16(aString, aLength

Because I didn't realize that there's a ctor accepting (|char *| and) |aLength|.
 Thanks ! (see bug 282819)

[1] Actually, it's a bit complicated. For Xft build, it's better to do that, but
in X11+FT2 build, removing nsFontPSAFM means that printing wouldn't work at all
in absence of freetype library. Perhaps, in a separate bug I have to just
enclose nsFontPSAFM with |#ifndef MOZ_ENABLE_XFT|
(In reply to comment #30)
> (In reply to comment #29)
> > Also, you may as well put the DrawString(char*) implementation on nsFontPS so it
> > can be shared, since it looks the same.  The same for GetWidth.
> 
> No, I can't unless I get rid of nsFontPSAFM when MOZ_ENABLE_FREETYPE2 |

Sorry. Forget about this non-sense.
(In reply to comment #30)

>  I get rid of nsFontPSAFM when MOZ_ENABLE_FREETYPE2 |
> MOZ_ENABLE_XFT is set, which I may as well do. [
...
> in absence of freetype library. Perhaps, in a separate bug I have to just
> enclose nsFontPSAFM with |#ifndef MOZ_ENABLE_XFT|

Oops. I forgot that 'freetype printing' can be turned off with 'pref'. So, I
should keep nsFontPSAFM no matter what. 

I replaced the elememnt-by-element conversion of char to PRUnichar with
NS_ConvertASCIItoUTF16.
Attachment #174772 - Attachment is obsolete: true
Attachment #174792 - Flags: superreview?(bzbarsky)
Attachment #174792 - Flags: review?(kherron+mozilla)
Attachment #174772 - Flags: superreview?(bzbarsky)
Just in case someone in the US tries to print sample PS output files (mentioned
in comment #20 and comment #22), they're all for A4 paper so that they wouldn't
get printed with US letter paper loaded. For testing purpose only, you may get
rid of   the following lines:

/setpagedevice where
{ pop 1 dict
  dup /PageSize [ 595.25 841.9 ] put
  setpagedevice
} if
Comment on attachment 174792 [details] [diff] [review]
patch (almost same) without nsAutoBuffer

I hadn't really looked at the subset code in nsPSFontGenerator before, but now
that I have I wonder if it couldn't be replaced with an nsCompressedCharMap
(intl/unicharutil/util/nsCompressedCharMap.h) at some point in the future.

Anyway, I just have some nits to pick:

>Index: gfx/src/ps/nsPostScriptObj.cpp
>-void nsPostScriptObj::setfont(const nsCString aFontName, PRUint32 aHeight)
>+void nsPostScriptObj::setfont(const nsCString& aFontName, PRUint32 aHeight,
>+                              PRInt32 aSubFont)
> {
>-  fprintf(mScriptFP, "%d /%s Msf\n", aHeight, aFontName.get());
>+  fprintf(mScriptFP, "%d /%s%s Msf\n", aHeight, aFontName.get(),
>+          aSubFont >= 0 ? nsPrintfCString(".Set%d", aSubFont).get() : "");
> }

This seems unnecessarily convoluted, and commonly calls *printf() twice where a
single call could do the job. it looks as though the aSubFont test is really a
"was I called with two or three arguments" test? If so, could we just have
separate two-arg and three-arg versions of this function? Or else just:

    if (aSubFont < 0)
      fprintf(...);
    else
      fprintf(...);


>Index: gfx/src/ps/nsType1.cpp
>+  // output mandatory 512 0's
>+  const static char *sixtyFourZeros =  
>+      "0000000000000000000000000000000000000000000000000000000000000000\n";

Could you make that "const static char sixtyFourZeros[]"? This avoids creating
a pointer in the data segment along with the text of the string.

Other than that, this all looks fine.
Attachment #174792 - Flags: review?(kherron+mozilla) → review+
Comment on attachment 174792 [details] [diff] [review]
patch (almost same) without nsAutoBuffer

>Index: gfx/src/ps/nsFontMetricsPS.cpp
>+nsPSFontGenerator::AddToSubset(PRUnichar aChar)
>+  PRInt32 index = mSubset.FindChar(aChar);

How big does mSubset get, typically?  This looks like it makes printing O(N^M)
where N is the number of chars and M is the number of different chars (so eg
printing a "all of Unicode" table would be painful).

If this is an issue, file a followup bug on it so we can figure out how to
resolve it?

>Index: gfx/src/ps/nsPostScriptObj.cpp
>+nsPostScriptObj::show(const PRUnichar* aTxt, int aLen,
>+    // XXX This is a little inefficient, but printing is not perf. critical. 

Is that inefficient like O(N^2) or worse?  Printing shouldn't hang the app
either, and algorithmic ineffieciency (as opposed to computational
inefficiency) has a way of doing that...  Again, file a followup bug if this
explodes badly on large pages or pages with many different chars.

With that, sr=bzbarsky
Attachment #174792 - Flags: superreview?(bzbarsky) → superreview+
Thanks for r/sr. Kenneth's comments were addressed when it's checked in.

(In reply to comment #36)
> (From update of attachment 174792 [details] [diff] [review] [edit])
> >Index: gfx/src/ps/nsFontMetricsPS.cpp
> >+nsPSFontGenerator::AddToSubset(PRUnichar aChar)
> >+  PRInt32 index = mSubset.FindChar(aChar);
> 
> How big does mSubset get, typically?  This looks like it makes printing O(N^M)
> where N is the number of chars and M is the number of different chars (so eg
> printing a "all of Unicode" table would be painful).


 FindChar is O(M), right? Then, it's O(N * M) rather than O(N^M), isn't it?
That's still slow although for typical values of M (~100 for European text and
~1000 for CJK text) it's 'tolerable' even if N is large. As for extreme cases,
let's say we want to print the full Unicode character with a
'almost-Pan-unicode' font like Code2000 and Arial MS Unicode. M would be ~50,000
and N would be about the same (of course, N can be arbitrarily large)

> If this is an issue, file a followup bug on it so we can figure out how to
> resolve it?

Yes, there's certainly a room for improvement. I plan to address the issue in
bug 282418 when adding support for non-BMP characters. Yeah, two issues are
separate, but I think I have to use hash anyway (can't rely on FindChar any more
for UTF-32/UCS4. I can make one easily for nsArray, though) for non-BMP
characters so that it's not a bad idea to deal with them together.

 
> >Index: gfx/src/ps/nsPostScriptObj.cpp
> >+nsPostScriptObj::show(const PRUnichar* aTxt, int aLen,
> >+    // XXX This is a little inefficient, but printing is not perf. critical. 
> 
> Is that inefficient like O(N^2) or worse?  Printing shouldn't hang the app
> either, and algorithmic ineffieciency (as opposed to computational
> inefficiency) has a way of doing that...  Again, file a followup bug if this
> explodes badly on large pages or pages with many different chars.

This part is all right. The size of search space in |show()| is 255 max so that
it's O(N). 

Btw, taking care of the issue may not have a large perf. effect because not
using freetype glyph caching (bug 234035 comment #98. note that it's about the
screen rendering with gtk1+x11core+FT2) is likely to shadow the inefficiency
here. I'll take a profile for printing later.

Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
I'm the Firefox maintainer for Ubuntu, and we're using 1.0.7 in our forthcoming
release (codenamed Breezy).  I have a comment that seems relevant, although I'm
not 100% sure.  I'm replying in 222624 too.

We had a bug http://bugzilla.ubuntu.com/show_bug.cgi?id=10293 regarding the
appearance (depending on configuration) of - instead of the desired document - a
bizarre page with runic instructions to mess about with gs pswrite.

We didn't consider this acceptable, so we are configuring our firefox (which
always uses CUPS for printing) to always ask CUPS to prefilter the PostScript. 
This may give suboptimal output under some conditions but at least it always
produces the desired printout!

I will attach the patch (to all.js) here.  It seems unfortunate to me that this
situation isn't considered a bug upstream !
WARNING do not just apply this patch.  I'm giving it for completeness.	It will
not work on systems not using CUPS.
(In reply to comment #38)
> I'm the Firefox maintainer for Ubuntu, and we're using 1.0.7 in our forthcoming
> release (codenamed Breezy).  I have a comment that seems relevant

It's not relevant here unless you also have the same problem (runic glyphs used
in place of what's to be used when printed) with 1.5beta or trunk build. Note
that my patch for this bug was not checked into 1.0.x branch. 
Gee, your mention of some bizzare ps output got me confused. Reading ubuntu bug
report, I realized what you're trying to solve was fixed by the patch here that
was NOT included in firefox 1.0.x. (now we produce PS level 1 output.) For ff
1.0.x that produces PS level 3 output, downgrading to PS level 2 or 1 is
necessary (as your change does) if you have a PS level 1 or level 2 printer. For
all other printers (non-PS printers, PS level 3 printers), you don't need that. 
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: