home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / gnu / utils / bug / 2291 < prev    next >
Encoding:
Text File  |  1993-01-01  |  12.2 KB  |  345 lines

  1. Newsgroups: gnu.utils.bug
  2. Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!wue.maus.DE!Fritz_Elfert
  3. From: Fritz_Elfert@wue.maus.DE (Fritz Elfert)
  4. Subject: bugs in fontutils-0.6/bzrto/ps
  5. Message-ID: <P16075@WUe.maus.de>
  6. Sender: gnulists@ai.mit.edu
  7. Organization: MausNet (Mitglied im IN e.V.)
  8. Distribution: gnu
  9. Date: Wed, 30 Dec 1992 14:08:00 GMT
  10. Approved: bug-gnu-utils@prep.ai.mit.edu
  11. Lines: 332
  12.  
  13. Hi!
  14.  
  15. I think i found two bugs in the program 'bzrto' of the GNU font-utilities
  16. Version 0.6:
  17.  
  18. I tested the the package by rendering the Times-Roman with Ghostscript 2.5.2
  19. using a size of 60 points and a resolution of 1000 dpi. After converting the
  20. bitmap with limn i used bzrto to produce an Adobe-Type-1 font to be compared
  21. with the original Times. Two misalignmets of the characters could be seen:
  22.  
  23.   First all characters where shifted to the right except those with a
  24. set-width smaller than then bounding-box (negative left-side-bearing).
  25.  
  26.   Second many characters are not positioned correctly in relation to the
  27. baseline. Many accented characters have their accents positioned wrong.
  28.  
  29. All those error did not appear in Type-3 fonts, so i took a closer look to
  30. the file 'pstype1.c' and found several things.
  31.  
  32. The reason for the first bug is that the hsbw-command at the start of each
  33. character alrady defines the starting x-coordinate of the character, and this
  34. value is repeated in the first rmoveto-command. The result is, that all
  35. left-side-bearings are multiplied by two. I corrected that by replacing the
  36. lsb-parameter at the first line of end_char() by a zero-constant.
  37.  
  38. The reason for the second bug is simply a cumulation of successive rounding-
  39. errors during conversion of absolute real coordinates to relative integer
  40. coordinates for the Type-1-Charstrings. I included three font-listings of
  41. the character 'Agrave'
  42.  
  43. First here is the Type-3 listing:
  44.  
  45. /Agrave [ 7.251 0 0.132 -0.012 7.106 8.949 {
  46.   4.228 7.227 moveto
  47.   4.173 7.303  4.100 7.363  4.036 7.432  curveto
  48.   3.505 7.974 lineto
  49.   3.011 8.468 lineto
  50.   2.801 8.678  2.486 9.099  2.144 8.903  curveto
  51.   2.058 8.853  2.005 8.759  2.000 8.660  curveto
  52.   1.994 8.542  2.041 8.422  2.121 8.335  curveto
  53.   2.163 8.290  2.214 8.250  2.264 8.215  curveto
  54.   3.300 7.559 lineto
  55.   3.662 7.330 lineto
  56.   3.708 7.301  3.755 7.264  3.806 7.242  curveto
  57.   3.844 7.225  3.874 7.227  3.914 7.227  curveto
  58.   4.228 7.227 lineto
  59.   closepath
  60. * 0.145 0.193 moveto
  61.   0.145 0 lineto
  62.   2.144 0 lineto
  63.   2.144 0.193 lineto
  64.   1.102 0.193  1.505 0.913  1.747 1.518  curveto
  65.   1.997 2.140 lineto
  66.   2.021 2.168  2.050 2.167  2.084 2.168  curveto
  67.   4.517 2.168 lineto
  68.   4.564 2.168  4.606 2.174  4.636 2.130  curveto
  69.   4.684 2.063  4.710 1.955  4.744 1.879  curveto
  70.   4.877 1.579  5.201 0.890  5.221 0.590  curveto
  71.   5.248 0.197  4.806 0.193  4.529 0.193  curveto
  72.   4.529 0 lineto
  73.   7.094 0 lineto
  74.   7.094 0.193 lineto
  75.   6.877 0.210  6.706 0.243  6.552 0.415  curveto
  76.   6.499 0.475  6.450 0.544  6.412 0.614  curveto
  77.   6.109 1.166  5.881 1.773  5.627 2.349  curveto
  78.   4.396 5.155 lineto
  79.   3.853 6.396 lineto
  80.   3.689 6.750 lineto
  81.   3.668 6.770  3.641 6.769  3.613 6.769  curveto
  82.   3.565 6.769 lineto
  83.   3.529 6.769  3.495 6.773  3.470 6.741  curveto
  84.   2.815 5.203 lineto
  85.   1.703 2.578 lineto
  86.   1.475 2.051  0.998 0.810  0.659 0.422  curveto
  87.   0.519 0.262  0.348 0.209  0.145 0.193  curveto
  88.   closepath
  89.   3.336 5.324 moveto
  90.   3.452 5.035 lineto
  91.   3.644 4.577 lineto
  92.   4.221 3.204 lineto
  93.   4.481 2.578 lineto
  94.   2.168 2.578 lineto
  95.   2.992 4.553 lineto
  96.   3.312 5.324 lineto
  97.   3.336 5.324 lineto
  98.   closepath
  99.   fill } ] def
  100.  
  101. The y-component of the moveto following the first closepath. (line marked *)
  102. is 0.193. Next here ist the decoded Type-1 listing of the same character
  103. (the patch at the hsbw-command already is incuded):
  104.  
  105. /Agrave
  106. {0 725 hsbw 422 722 rmoveto -5 7 -7 6 -6 6 rrcurveto -53 54 rlineto -49 49
  107. rlineto -20 20 -31 42 -34 -19 rrcurveto -8 -4 -5 -9 0 -9 rrcurveto 0 -11 4 -12
  108. 7 -8 rrcurveto 4 -4 5 -4 5 -3 rrcurveto 103 -65 rlineto 36 -22 rlineto 4 -2 4
  109. -3 5 -2 rrcurveto 3 -1 3 0 4 0 rrcurveto 31 hlineto closepath -408 -703
  110. *
  111. rmoveto -19 vlineto 199 hlineto 19 vlineto -104 0 40 72 24 60 rrcurveto 25 62
  112. rlineto 2 2 2 0 3 0 rrcurveto 243 hlineto 4 0 4 0 3 -4 rrcurveto 4 -6 2 -10 3
  113. -7 rrcurveto 13 -30 32 -68 2 -29 rrcurveto 2 -39 -44 0 -27 0 rrcurveto -19
  114. vlineto 256 hlineto 19 vlineto -21 1 -17 3 -15 17 rrcurveto -5 6 -4 6 -3 7
  115. rrcurveto -30 55 -22 60 -25 57 rrcurveto -123 280 rlineto -54 124 rlineto -16
  116. 35 rlineto -2 1 -2 0 -2 0 rrcurveto -4 hlineto -3 0 -3 0 -2 -3 rrcurveto -65
  117. -153 rlineto -111 -262 rlineto -22 -52 -47 -124 -33 -38 rrcurveto -13 -15 -17
  118. -5 -20 -1 rrcurveto closepath 319 513 rmoveto 11 -28 rlineto 19 -45 rlineto 57
  119. -137 rlineto 25 -62 rlineto -231 hlineto 82 197 rlineto 31 77 rlineto 2
  120. hlineto closepath -333 -532 rmoveto endchar } def
  121.  
  122. By simply adding all y-components until the Asterisk-mark one should get 19.
  123. Unfortunately all rounding errors cumulate yielding a result of 25. The result
  124. is, that the character is 'raised' above the baseline. I corrected this bug by
  125. using absolute_cs_number() at any place where previously cs_number() was used.
  126. The conversion to 'Adobe-Unis' had to be done before the difference of two
  127. consecutive points is calculated. The result can be seen in the following
  128. listing of the character which has been produced by the completely patched
  129. program:
  130.  
  131. /Agrave
  132. {0 725 hsbw 422 722 rmoveto -5 8 -8 6 -6 7 rrcurveto -53 54 rlineto -49 49
  133. rlineto -21 21 -32 42 -34 -19 rrcurveto -9 -5 -5 -10 -1 -9 rrcurveto 0 -12 5
  134. -12 8 -9 rrcurveto 4 -4 5 -4 5 -4 rrcurveto 104 -66 rlineto 36 -22 rlineto 4
  135. -3 5 -4 5 -2 rrcurveto 4 -2 3 0 4 0 rrcurveto 31 hlineto closepath -408 -703
  136. rmoveto -19 vlineto 200 hlineto 19 vlineto -104 0 40 72 24 60 rrcurveto 25 63
  137. rlineto 3 2 2 0 4 0 rrcurveto 243 hlineto 5 0 4 1 3 -4 rrcurveto 5 -7 3 -11 3
  138. -8 rrcurveto 13 -30 33 -69 2 -29 rrcurveto 2 -40 -44 0 -28 0 rrcurveto -19
  139. vlineto 257 hlineto 19 vlineto -22 2 -17 3 -15 17 rrcurveto -6 6 -4 7 -4 7
  140. rrcurveto -31 55 -22 61 -26 57 rrcurveto -123 281 rlineto -54 124 rlineto -17
  141. 36 rlineto -2 1 -2 0 -3 0 rrcurveto -5 hlineto -4 0 -3 1 -3 -3 rrcurveto -65
  142. -154 rlineto -111 -263 rlineto -23 -52 -48 -124 -34 -39 rrcurveto -14 -16 -17
  143. -6 -20 -1 rrcurveto closepath 319 513 rmoveto 12 -29 rlineto 19 -46 rlineto 58
  144. -137 rlineto 26 -63 rlineto -232 hlineto 83 198 rlineto 32 77 rlineto 2
  145. hlineto closepath -333 -532 rmoveto endchar } def
  146.  
  147.  
  148. Finally here is the context-diff of the patched (pstype1x.c) and distributed
  149. (pstype1o.c) versions of pstype1.c:
  150.  
  151. *** pstype1o.c  Wed Dec 30 14:52:40 1992
  152. --- pstype1x.c  Tue Dec 29 15:56:52 1992
  153. ***************
  154. *** 105,111 ****
  155. --- 105,114 ----
  156.   static void end_char (real, real);
  157.   static void cs_byte (one_byte, variable_string *);
  158.   static variable_string cs_encrypt (variable_string);
  159. + /* Replaced by absolute_cs_number
  160. +    F. Elfert, 29. Dec 1992
  161.   static void cs_number (real, variable_string *);
  162. + */
  163.   static void init_charstring_buffers (void);
  164.   static void out_bb_char
  165.     (real_bounding_box_type *, real_coordinate_type *, bzr_char_type);
  166. ***************
  167. *** 356,363 ****
  168.   static void
  169.   end_char (real lsb, real set_width)
  170.   {
  171. !   cs_number (lsb, &pre_charstring_buffer);
  172. !   cs_number (set_width, &pre_charstring_buffer);
  173.     cs_byte (T1_HSBW, &pre_charstring_buffer);
  174.  
  175.     cs_byte (T1_ENDCHAR, &charstring_buffer);
  176. --- 359,374 ----
  177.   static void
  178.   end_char (real lsb, real set_width)
  179.   {
  180. ! /*
  181. !    Changed because lsb defines starting-point and this is point
  182. !    is output by the first move-command of the char. I'm not shure
  183. !    whether ist better to eliminate the first move-command or setting
  184. !    the lsb to zero. However ist easier doing it here.
  185. !    F. Elfert 29. Dec 1992
  186. ! */
  187. !   absolute_cs_number (/*lsb*/ 0, &pre_charstring_buffer);
  188. !
  189. !   absolute_cs_number (points_to_adobes(set_width), &pre_charstring_buffer);
  190.     cs_byte (T1_HSBW, &pre_charstring_buffer);
  191.  
  192.     cs_byte (T1_ENDCHAR, &charstring_buffer);
  193. ***************
  194. *** 527,534 ****
  195.   static void
  196.   out_point (real_coordinate_type *current, real_coordinate_type p)
  197.   {
  198. !   cs_number (p.x - current->x, &charstring_buffer);
  199. !   cs_number (p.y - current->y, &charstring_buffer);
  200.     *current = p;
  201.   }
  202.  
  203. --- 538,545 ----
  204.   static void
  205.   out_point (real_coordinate_type *current, real_coordinate_type p)
  206.   {
  207. !   absolute_cs_number (points_to_adobes(p.x) - points_to_adobes(current->x),
  208. &charstring_buffer);
  209. !   absolute_cs_number (points_to_adobes(p.y) - points_to_adobes(current->y),
  210. &charstring_buffer);
  211.     *current = p;
  212.   }
  213.  
  214. ***************
  215. *** 571,577 ****
  216.            algorithm, perhaps.)  */
  217.         if (!y_equal)
  218.           {
  219. !           cs_number (p.y - current->y, &charstring_buffer);
  220.             cs_byte (v_opcode, &charstring_buffer);
  221.             current->y = p.y;
  222.           }
  223. --- 582,588 ----
  224.            algorithm, perhaps.)  */
  225.         if (!y_equal)
  226.           {
  227. !           absolute_cs_number (points_to_adobes(p.y) -
  228. points_to_adobes(current->y), &charstring_buffer);
  229.             cs_byte (v_opcode, &charstring_buffer);
  230.             current->y = p.y;
  231.           }
  232. ***************
  233. *** 578,584 ****
  234.       }
  235.     else if (y_equal)
  236.       {
  237. !       cs_number (p.x - current->x, &charstring_buffer);
  238.         cs_byte (h_opcode, &charstring_buffer);
  239.         current->x = p.x;
  240.       }
  241. --- 589,595 ----
  242.       }
  243.     else if (y_equal)
  244.       {
  245. !       absolute_cs_number (points_to_adobes(p.x) -
  246. points_to_adobes(current->x), &charstring_buffer);
  247.         cs_byte (h_opcode, &charstring_buffer);
  248.         current->x = p.x;
  249.       }
  250. ***************
  251. *** 600,609 ****
  252.     if (epsilon_equal (current->x, CONTROL1 (s).x)
  253.         && epsilon_equal (CONTROL2 (s).y, END_POINT (s).y))
  254.       {
  255. !       cs_number (CONTROL1 (s).y - current->y, &charstring_buffer);
  256.         current->y = CONTROL1 (s).y;
  257.         out_point (current, CONTROL2 (s));
  258. !       cs_number (END_POINT (s).x - current->x, &charstring_buffer);
  259.         current->x = END_POINT (s).x;
  260.         cs_byte (T1_VHCURVETO, &charstring_buffer);
  261.       }
  262. --- 611,620 ----
  263.     if (epsilon_equal (current->x, CONTROL1 (s).x)
  264.         && epsilon_equal (CONTROL2 (s).y, END_POINT (s).y))
  265.       {
  266. !       absolute_cs_number (points_to_adobes(CONTROL1 (s).y) -
  267. points_to_adobes(current->y), &charstring_buffer);
  268.         current->y = CONTROL1 (s).y;
  269.         out_point (current, CONTROL2 (s));
  270. !       absolute_cs_number (points_to_adobes(END_POINT (s).x) -
  271. points_to_adobes(current->x), &charstring_buffer);
  272.         current->x = END_POINT (s).x;
  273.         cs_byte (T1_VHCURVETO, &charstring_buffer);
  274.       }
  275. ***************
  276. *** 612,621 ****
  277.     else if (epsilon_equal (current->y, CONTROL1 (s).y)
  278.         && epsilon_equal (CONTROL2 (s).x, END_POINT (s).x))
  279.       {
  280. !       cs_number (CONTROL1 (s).x - current->x, &charstring_buffer);
  281.         current->x = CONTROL1 (s).x;
  282.         out_point (current, CONTROL2 (s));
  283. !       cs_number (END_POINT (s).y - current->y, &charstring_buffer);
  284.         current->y = END_POINT (s).y;
  285.         cs_byte (T1_HVCURVETO, &charstring_buffer);
  286.       }
  287. --- 623,632 ----
  288.     else if (epsilon_equal (current->y, CONTROL1 (s).y)
  289.         && epsilon_equal (CONTROL2 (s).x, END_POINT (s).x))
  290.       {
  291. !       absolute_cs_number (points_to_adobes(CONTROL1 (s).x) -
  292. points_to_adobes(current->x), &charstring_buffer);
  293.         current->x = CONTROL1 (s).x;
  294.         out_point (current, CONTROL2 (s));
  295. !       absolute_cs_number (points_to_adobes(END_POINT (s).y) -
  296. points_to_adobes(current->y), &charstring_buffer);
  297.         current->y = END_POINT (s).y;
  298.         cs_byte (T1_HVCURVETO, &charstring_buffer);
  299.       }
  300. ***************
  301. *** 652,657 ****
  302. --- 663,672 ----
  303.   /* This appends to BUFFER the charstring encoding of the number N,
  304.      assumed to be in printer's points.  */
  305.  
  306. + /*
  307. +    This routine now is not nacessary any more.
  308. +    F. Elfert, 29. Dec 1992
  309. +
  310.   static void
  311.   cs_number (real n, variable_string *buffer)
  312.   {
  313. ***************
  314. *** 659,665 ****
  315.  
  316.     absolute_cs_number (n_in_adobes, buffer);
  317.   }
  318. !
  319.  
  320.   /* See section 6.2 of the book Adobe Type 1 Font Format.  */
  321.  
  322. --- 674,680 ----
  323.  
  324.     absolute_cs_number (n_in_adobes, buffer);
  325.   }
  326. ! */
  327.  
  328.   /* See section 6.2 of the book Adobe Type 1 Font Format.  */
  329.  
  330. =============================================================================
  331.  
  332. I hope this helps you improving these excellent tools.
  333.  
  334. Happy new Year!
  335.  
  336. -Fritz (fritz_elfert@wue.maus.de)
  337.  
  338. PS: Messages in the german .maus domain are restricted to 16k per mail. PLEASE
  339.     do NOT send large listing etc. Thank you!
  340.  
  341.  
  342. Tschau
  343.   Fritz
  344.  
  345.