[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    Re: [Fwd: Bug#30364: hang cpu when preview a file with MS Windows font (comic,trebuchet)]
From:       Vadim Plessky <lucy-ples () mtu-net ! ru>
Date:       2001-08-07 18:03:18
[Download RAW message or body]

On Tuesday 07 August 2001 12:08, Michael Goffioul wrote:
|   Does anybody have an idea about this problem?
|
|   Michael.
|

Yes, for sure.
I believe this problem was already discussed on kde-devel,
see thread "KWord and printing documents with truetype fonts" from 19/06/2001
(started by Nils Holland)

See attached patch by Lars Knoll.
You should apply it on QT and recompile QT. Should help ;-)

BTW: as far as I know this patch was comitted to QT-copy.
I don't use QT-copy and can't confirm, though.

|   Michael Goffioul wrote:
|   > > I try to print (using print to file Postscript) 2 pages of text
|   > > And open the file with GV or 'KDE PS viewer'.
|   > >
|   > > When the text is in MS Windows font (comic,trebuchet),
|   > > GV and 'KDE PS viewer' render the beginning of the text and then
|   > > hang cpu (the cpu is used 100%, infinite loop)
|   > > =>the result is the same using kate or kword
|   > > =>when I use another font (like helvetica), everything is rigth
|   > >
|   > > The same test with 'print to file PDF/Acrobat':
|   > > When the text is in MS Windows font (comic,trebuchet),
|   > > the result 'print.pdf' have a size of 0KB and can't be open
|   > > If I choose another font, , everything is rigth.
|   >
|   > I don't think it's a kdeprint related problems. When you print to a
|   > file, kdeprint does nothing: Qt generated PS data are copied to a local
|   > file, and that's it. I tried on my system, kwrite with a couple of
|   > TTF fonts: in most cases, everything is OK, but I have the same problem
|   > with a few TTF fonts ("Comic sans ms").
|   >
|   > The problem can be:
|   >  - either in GS failing to handle some embedded M$ TTF fonts
|   >  - or in Qt producing corrupted PS data

It is QT bug.
According to Lars Knoll, problem is fixed by attached patch.

Can somebody who compile regulary test this patch (printing of several 
TrueType fonts, inlc. for example Times New Roman)?

|   >
|   > Don't know however where the problem is. My system:
|   >  - XFree86-4.0.3
|   >  - GS-6.50
|   >  - Qt-2.3.0
|   >  - KDE-CVS
|   >
|   > Bye.
|   > Michael.

-- 

Vadim Plessky
http://kde2.newmail.ru  (English)
33 Window Decorations and 6 Widget Styles for KDE
http://kde2.newmail.ru/kde_themes.html
Do you have Arial font installed? Just test it!
http://kde2.newmail.ru/font_test_arial.html

["qpsprinter.diff" (text/x-diff)]

==== //depot/qt/2.3/src/kernel/qpsprinter.cpp#49 (text) - \
//depot/qt/2.3/src/kernel/qpsprinter.cpp#51 (text) ==== content @@ -1892,6 +1892,39 \
@@  #endif
 };
 
+// duplicate entries in the glyph list. Do not download these, to avoid
+// doubly defined gl;yphs
+static const unsigned short duplicateEntries[] = {
+    0x00A0,
+	0x0394,
+	0x03a9,
+	0xf6c1,
+	0x021a,
+	0x2215,
+	0x00ad,
+	0x02c9,
+	0x03bc,
+	0x2219,
+	0xf6c2,
+	0x00a0,
+	0x021b,
+	0x0
+	};
+
+static inline bool duplicate( unsigned short unicode )
+{
+    const unsigned short *g = duplicateEntries;
+    bool duplicate = FALSE;
+    while( *g ) {
+	if ( *g == unicode ) {
+	    duplicate = TRUE;
+	    break;
+	}
+	g++;
+    }
+    return duplicate;
+}
+
 // ---------------------------------------------------------------------
 // postscript font substitution dictionary. We assume every postscript printer has \
at least  // Helvetica, Times, Courier and Symbol
@@ -2611,6 +2644,13 @@
   Q_UINT16 fraction;
 } Fixed; // 16.16 bit fixed-point number
 
+static float f2dot14( ushort s )
+{
+    float f = ((float)( s & 0x3fff ))/ 16384.;
+    f += (s & 0x8000) ? ( (s & 0x4000) ? -1 : -2 ) : ( (s & 0x4000) ? 1 : 0 );
+    return f;
+}
+    
 static ULONG getULONG(BYTE *p)
 {
   int x;
@@ -3258,7 +3298,7 @@
     QString glyphname;
     int l = 0;
     unsigned short unicode = unicode_for_glyph( glyphindex );
-    if ( unicode == 0xffff ) // workaround
+    if ( unicode == 0xffff || duplicate( unicode ) ) // workaround
         glyphname.sprintf("G%04x", glyphindex );
     else {
     while( unicodetoglyph[l].u < unicode )
@@ -4124,92 +4164,97 @@
   USHORT glyphIndex;
   int arg1;
   int arg2;
-  USHORT xscale;
-  USHORT yscale;
-  USHORT scale01;
-  USHORT scale10;
+  float xscale = 1;
+  float yscale = 1;
+  float scale01 = 0;
+  float scale10 = 0;
 
   /* Once around this loop for each component. */
   do {
-    flags = getUSHORT(glyph);   /* read the flags word */
-    glyph += 2;
+      flags = getUSHORT(glyph);   /* read the flags word */
+      glyph += 2;
 
-    glyphIndex = getUSHORT(glyph);      /* read the glyphindex word */
-    glyph += 2;
+      glyphIndex = getUSHORT(glyph);      /* read the glyphindex word */
+      glyph += 2;
 
-    if(flags & ARG_1_AND_2_ARE_WORDS) {
+      if(flags & ARG_1_AND_2_ARE_WORDS) {
                                 /* The tt spec. seems to say these are signed. */
-      arg1 = getSHORT(glyph);
-      glyph += 2;
-      arg2 = getSHORT(glyph);
-      glyph += 2;
-    } else {                    /* The tt spec. does not clearly indicate */
+	  arg1 = getSHORT(glyph);
+	  glyph += 2;
+	  arg2 = getSHORT(glyph);
+	  glyph += 2;
+      } else {                    /* The tt spec. does not clearly indicate */
                                 /* whether these values are signed or not. */
-      arg1 = *(glyph++);
-      arg2 = *(glyph++);
-    }
+	  arg1 = *(glyph++);
+	  arg2 = *(glyph++);
+      }
 
-    if(flags & WE_HAVE_A_SCALE) {
-      xscale = yscale = getUSHORT(glyph);
-      glyph += 2;
-      scale01 = scale10 = 0;
-    } else if(flags & WE_HAVE_AN_X_AND_Y_SCALE) {
-      xscale = getUSHORT(glyph);
-      glyph += 2;
-      yscale = getUSHORT(glyph);
-      glyph += 2;
-      scale01 = scale10 = 0;
-    } else if(flags & WE_HAVE_A_TWO_BY_TWO) {
-      xscale = getUSHORT(glyph);
-      glyph += 2;
-      scale01 = getUSHORT(glyph);
-      glyph += 2;
-      scale10 = getUSHORT(glyph);
-      glyph += 2;
-      yscale = getUSHORT(glyph);
-      glyph += 2;
-    } else {
-      xscale = yscale = scale01 = scale10 = 0;
-    }
+      if(flags & WE_HAVE_A_SCALE) {
+	  xscale = yscale = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+      } else if(flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+	  xscale = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+	  yscale = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+      } else if(flags & WE_HAVE_A_TWO_BY_TWO) {
+	  xscale = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+	  scale01 = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+	  scale10 = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+	  yscale = f2dot14( getUSHORT(glyph) );
+	  glyph += 2;
+      }
 
-    /* Debugging */
+      /* Debugging */
 #ifdef DEBUG_TRUETYPE
-    fprintf(stderr,"% flags=%d, arg1=%d, arg2=%d, xscale=%d, yscale=%d, scale01=%d, \
                scale10=%d\n",
-            (int)flags,arg1,arg2,(int)xscale,(int)yscale,(int)scale01,(int)scale10);
+      fprintf(stderr,"% flags=%d, arg1=%d, arg2=%d, xscale=%d, yscale=%d, \
scale01=%d, scale10=%d\n", +	      \
(int)flags,arg1,arg2,(int)xscale,(int)yscale,(int)scale01,(int)scale10);  #endif
 
-    /* If we have an (X,Y) shif and it is non-zero, */
-    /* translate the coordinate system. */
-    if( flags & ARGS_ARE_XY_VALUES ) {
-      if( arg1 != 0 || arg2 != 0 ) {
-        s <<"gsave ";
-        s << topost(arg1);
-        s << " ";
-        s << topost(arg2);
-        s << " translate\n";
+
+      if ( (flags & ARGS_ARE_XY_VALUES) != ARGS_ARE_XY_VALUES ) {
+	  s << "% unimplemented shift, arg1=" << arg1;
+	  s << ", arg2=" << arg2 << "\n";
+	  arg1 = arg2 = 0;
+      }	
 
-        //fprintf(stderr,"gsave %d %d translate\n", topost(arg1), topost(arg2) );
+      /* If we have an (X,Y) shif and it is non-zero, */
+      /* translate the coordinate system. */
+      if ( flags & (WE_HAVE_A_TWO_BY_TWO|WE_HAVE_AN_X_AND_Y_SCALE) ) {
+#if 0
+	  // code similar to this would be needed for two_by_tow
+	  s << "gsave [ " << xscale << " " << scale01 << " " << scale10 << " "
+	    << yscale << " " << topost(arg1) << " " << topost(arg2) << "] SM\n";
+#endif
+	  if ( flags & WE_HAVE_A_TWO_BY_TWO )
+	      s << "% Two by two transformation, unimplemented\n";
+	  s <<"gsave " << topost(arg1);
+	  s << " " << topost(arg2);
+	  s << " translate\n";
+	  s << xscale << " " << yscale << " scale\n";
+      } else if ( flags & ARGS_ARE_XY_VALUES && ( arg1 != 0 || arg2 != 0 ) ) {
+	  s <<"gsave " << topost(arg1);
+	  s << " " << topost(arg2);
+	  s << " translate\n";
       }
-    } else {
-      s << "% unimplemented shift, arg1=";
-      s << arg1;
-      s << ", arg2=";
-      s << arg2;
-      s << "\n";
-    }
 
-    /* Invoke the CharStrings procedure to print the component. */
-    s << "false CharStrings /";
-    s << glyphName(glyphIndex);
-    s << " get exec\n";
+      /* Invoke the CharStrings procedure to print the component. */
+      s << "false CharStrings /";
+      s << glyphName(glyphIndex);
+      s << " get exec\n";
 
-    //  printf("false CharStrings /%s get exec\n",
-    //ttfont_CharStrings_getname(font,glyphIndex));
+      //  printf("false CharStrings /%s get exec\n",
+      //ttfont_CharStrings_getname(font,glyphIndex));
 
-    /* If we translated the coordinate system, */
-    /* put it back the way it was. */
-    if( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) )
-      s <<"grestore ";
+      /* If we translated the coordinate system, */
+      /* put it back the way it was. */
+      if( (flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) ) ||
+	  ( flags & (WE_HAVE_A_TWO_BY_TWO|WE_HAVE_AN_X_AND_Y_SCALE) ) ) {
+	  s <<"grestore ";
+      }
   } while(flags & MORE_COMPONENTS);
 }
 


>> Visit http://master.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic