home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: gnu.utils.bug
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!wue.maus.DE!Fritz_Elfert
- From: Fritz_Elfert@wue.maus.DE (Fritz Elfert)
- Subject: bugs in fontutils-0.6/bzrto/ps
- Message-ID: <P16075@WUe.maus.de>
- Sender: gnulists@ai.mit.edu
- Organization: MausNet (Mitglied im IN e.V.)
- Distribution: gnu
- Date: Wed, 30 Dec 1992 14:08:00 GMT
- Approved: bug-gnu-utils@prep.ai.mit.edu
- Lines: 332
-
- Hi!
-
- I think i found two bugs in the program 'bzrto' of the GNU font-utilities
- Version 0.6:
-
- I tested the the package by rendering the Times-Roman with Ghostscript 2.5.2
- using a size of 60 points and a resolution of 1000 dpi. After converting the
- bitmap with limn i used bzrto to produce an Adobe-Type-1 font to be compared
- with the original Times. Two misalignmets of the characters could be seen:
-
- First all characters where shifted to the right except those with a
- set-width smaller than then bounding-box (negative left-side-bearing).
-
- Second many characters are not positioned correctly in relation to the
- baseline. Many accented characters have their accents positioned wrong.
-
- All those error did not appear in Type-3 fonts, so i took a closer look to
- the file 'pstype1.c' and found several things.
-
- The reason for the first bug is that the hsbw-command at the start of each
- character alrady defines the starting x-coordinate of the character, and this
- value is repeated in the first rmoveto-command. The result is, that all
- left-side-bearings are multiplied by two. I corrected that by replacing the
- lsb-parameter at the first line of end_char() by a zero-constant.
-
- The reason for the second bug is simply a cumulation of successive rounding-
- errors during conversion of absolute real coordinates to relative integer
- coordinates for the Type-1-Charstrings. I included three font-listings of
- the character 'Agrave'
-
- First here is the Type-3 listing:
-
- /Agrave [ 7.251 0 0.132 -0.012 7.106 8.949 {
- 4.228 7.227 moveto
- 4.173 7.303 4.100 7.363 4.036 7.432 curveto
- 3.505 7.974 lineto
- 3.011 8.468 lineto
- 2.801 8.678 2.486 9.099 2.144 8.903 curveto
- 2.058 8.853 2.005 8.759 2.000 8.660 curveto
- 1.994 8.542 2.041 8.422 2.121 8.335 curveto
- 2.163 8.290 2.214 8.250 2.264 8.215 curveto
- 3.300 7.559 lineto
- 3.662 7.330 lineto
- 3.708 7.301 3.755 7.264 3.806 7.242 curveto
- 3.844 7.225 3.874 7.227 3.914 7.227 curveto
- 4.228 7.227 lineto
- closepath
- * 0.145 0.193 moveto
- 0.145 0 lineto
- 2.144 0 lineto
- 2.144 0.193 lineto
- 1.102 0.193 1.505 0.913 1.747 1.518 curveto
- 1.997 2.140 lineto
- 2.021 2.168 2.050 2.167 2.084 2.168 curveto
- 4.517 2.168 lineto
- 4.564 2.168 4.606 2.174 4.636 2.130 curveto
- 4.684 2.063 4.710 1.955 4.744 1.879 curveto
- 4.877 1.579 5.201 0.890 5.221 0.590 curveto
- 5.248 0.197 4.806 0.193 4.529 0.193 curveto
- 4.529 0 lineto
- 7.094 0 lineto
- 7.094 0.193 lineto
- 6.877 0.210 6.706 0.243 6.552 0.415 curveto
- 6.499 0.475 6.450 0.544 6.412 0.614 curveto
- 6.109 1.166 5.881 1.773 5.627 2.349 curveto
- 4.396 5.155 lineto
- 3.853 6.396 lineto
- 3.689 6.750 lineto
- 3.668 6.770 3.641 6.769 3.613 6.769 curveto
- 3.565 6.769 lineto
- 3.529 6.769 3.495 6.773 3.470 6.741 curveto
- 2.815 5.203 lineto
- 1.703 2.578 lineto
- 1.475 2.051 0.998 0.810 0.659 0.422 curveto
- 0.519 0.262 0.348 0.209 0.145 0.193 curveto
- closepath
- 3.336 5.324 moveto
- 3.452 5.035 lineto
- 3.644 4.577 lineto
- 4.221 3.204 lineto
- 4.481 2.578 lineto
- 2.168 2.578 lineto
- 2.992 4.553 lineto
- 3.312 5.324 lineto
- 3.336 5.324 lineto
- closepath
- fill } ] def
-
- The y-component of the moveto following the first closepath. (line marked *)
- is 0.193. Next here ist the decoded Type-1 listing of the same character
- (the patch at the hsbw-command already is incuded):
-
- /Agrave
- {0 725 hsbw 422 722 rmoveto -5 7 -7 6 -6 6 rrcurveto -53 54 rlineto -49 49
- rlineto -20 20 -31 42 -34 -19 rrcurveto -8 -4 -5 -9 0 -9 rrcurveto 0 -11 4 -12
- 7 -8 rrcurveto 4 -4 5 -4 5 -3 rrcurveto 103 -65 rlineto 36 -22 rlineto 4 -2 4
- -3 5 -2 rrcurveto 3 -1 3 0 4 0 rrcurveto 31 hlineto closepath -408 -703
- *
- rmoveto -19 vlineto 199 hlineto 19 vlineto -104 0 40 72 24 60 rrcurveto 25 62
- rlineto 2 2 2 0 3 0 rrcurveto 243 hlineto 4 0 4 0 3 -4 rrcurveto 4 -6 2 -10 3
- -7 rrcurveto 13 -30 32 -68 2 -29 rrcurveto 2 -39 -44 0 -27 0 rrcurveto -19
- vlineto 256 hlineto 19 vlineto -21 1 -17 3 -15 17 rrcurveto -5 6 -4 6 -3 7
- rrcurveto -30 55 -22 60 -25 57 rrcurveto -123 280 rlineto -54 124 rlineto -16
- 35 rlineto -2 1 -2 0 -2 0 rrcurveto -4 hlineto -3 0 -3 0 -2 -3 rrcurveto -65
- -153 rlineto -111 -262 rlineto -22 -52 -47 -124 -33 -38 rrcurveto -13 -15 -17
- -5 -20 -1 rrcurveto closepath 319 513 rmoveto 11 -28 rlineto 19 -45 rlineto 57
- -137 rlineto 25 -62 rlineto -231 hlineto 82 197 rlineto 31 77 rlineto 2
- hlineto closepath -333 -532 rmoveto endchar } def
-
- By simply adding all y-components until the Asterisk-mark one should get 19.
- Unfortunately all rounding errors cumulate yielding a result of 25. The result
- is, that the character is 'raised' above the baseline. I corrected this bug by
- using absolute_cs_number() at any place where previously cs_number() was used.
- The conversion to 'Adobe-Unis' had to be done before the difference of two
- consecutive points is calculated. The result can be seen in the following
- listing of the character which has been produced by the completely patched
- program:
-
- /Agrave
- {0 725 hsbw 422 722 rmoveto -5 8 -8 6 -6 7 rrcurveto -53 54 rlineto -49 49
- rlineto -21 21 -32 42 -34 -19 rrcurveto -9 -5 -5 -10 -1 -9 rrcurveto 0 -12 5
- -12 8 -9 rrcurveto 4 -4 5 -4 5 -4 rrcurveto 104 -66 rlineto 36 -22 rlineto 4
- -3 5 -4 5 -2 rrcurveto 4 -2 3 0 4 0 rrcurveto 31 hlineto closepath -408 -703
- rmoveto -19 vlineto 200 hlineto 19 vlineto -104 0 40 72 24 60 rrcurveto 25 63
- rlineto 3 2 2 0 4 0 rrcurveto 243 hlineto 5 0 4 1 3 -4 rrcurveto 5 -7 3 -11 3
- -8 rrcurveto 13 -30 33 -69 2 -29 rrcurveto 2 -40 -44 0 -28 0 rrcurveto -19
- vlineto 257 hlineto 19 vlineto -22 2 -17 3 -15 17 rrcurveto -6 6 -4 7 -4 7
- rrcurveto -31 55 -22 61 -26 57 rrcurveto -123 281 rlineto -54 124 rlineto -17
- 36 rlineto -2 1 -2 0 -3 0 rrcurveto -5 hlineto -4 0 -3 1 -3 -3 rrcurveto -65
- -154 rlineto -111 -263 rlineto -23 -52 -48 -124 -34 -39 rrcurveto -14 -16 -17
- -6 -20 -1 rrcurveto closepath 319 513 rmoveto 12 -29 rlineto 19 -46 rlineto 58
- -137 rlineto 26 -63 rlineto -232 hlineto 83 198 rlineto 32 77 rlineto 2
- hlineto closepath -333 -532 rmoveto endchar } def
-
-
- Finally here is the context-diff of the patched (pstype1x.c) and distributed
- (pstype1o.c) versions of pstype1.c:
-
- *** pstype1o.c Wed Dec 30 14:52:40 1992
- --- pstype1x.c Tue Dec 29 15:56:52 1992
- ***************
- *** 105,111 ****
- --- 105,114 ----
- static void end_char (real, real);
- static void cs_byte (one_byte, variable_string *);
- static variable_string cs_encrypt (variable_string);
- + /* Replaced by absolute_cs_number
- + F. Elfert, 29. Dec 1992
- static void cs_number (real, variable_string *);
- + */
- static void init_charstring_buffers (void);
- static void out_bb_char
- (real_bounding_box_type *, real_coordinate_type *, bzr_char_type);
- ***************
- *** 356,363 ****
- static void
- end_char (real lsb, real set_width)
- {
- ! cs_number (lsb, &pre_charstring_buffer);
- ! cs_number (set_width, &pre_charstring_buffer);
- cs_byte (T1_HSBW, &pre_charstring_buffer);
-
- cs_byte (T1_ENDCHAR, &charstring_buffer);
- --- 359,374 ----
- static void
- end_char (real lsb, real set_width)
- {
- ! /*
- ! Changed because lsb defines starting-point and this is point
- ! is output by the first move-command of the char. I'm not shure
- ! whether ist better to eliminate the first move-command or setting
- ! the lsb to zero. However ist easier doing it here.
- ! F. Elfert 29. Dec 1992
- ! */
- ! absolute_cs_number (/*lsb*/ 0, &pre_charstring_buffer);
- !
- ! absolute_cs_number (points_to_adobes(set_width), &pre_charstring_buffer);
- cs_byte (T1_HSBW, &pre_charstring_buffer);
-
- cs_byte (T1_ENDCHAR, &charstring_buffer);
- ***************
- *** 527,534 ****
- static void
- out_point (real_coordinate_type *current, real_coordinate_type p)
- {
- ! cs_number (p.x - current->x, &charstring_buffer);
- ! cs_number (p.y - current->y, &charstring_buffer);
- *current = p;
- }
-
- --- 538,545 ----
- static void
- out_point (real_coordinate_type *current, real_coordinate_type p)
- {
- ! absolute_cs_number (points_to_adobes(p.x) - points_to_adobes(current->x),
- &charstring_buffer);
- ! absolute_cs_number (points_to_adobes(p.y) - points_to_adobes(current->y),
- &charstring_buffer);
- *current = p;
- }
-
- ***************
- *** 571,577 ****
- algorithm, perhaps.) */
- if (!y_equal)
- {
- ! cs_number (p.y - current->y, &charstring_buffer);
- cs_byte (v_opcode, &charstring_buffer);
- current->y = p.y;
- }
- --- 582,588 ----
- algorithm, perhaps.) */
- if (!y_equal)
- {
- ! absolute_cs_number (points_to_adobes(p.y) -
- points_to_adobes(current->y), &charstring_buffer);
- cs_byte (v_opcode, &charstring_buffer);
- current->y = p.y;
- }
- ***************
- *** 578,584 ****
- }
- else if (y_equal)
- {
- ! cs_number (p.x - current->x, &charstring_buffer);
- cs_byte (h_opcode, &charstring_buffer);
- current->x = p.x;
- }
- --- 589,595 ----
- }
- else if (y_equal)
- {
- ! absolute_cs_number (points_to_adobes(p.x) -
- points_to_adobes(current->x), &charstring_buffer);
- cs_byte (h_opcode, &charstring_buffer);
- current->x = p.x;
- }
- ***************
- *** 600,609 ****
- if (epsilon_equal (current->x, CONTROL1 (s).x)
- && epsilon_equal (CONTROL2 (s).y, END_POINT (s).y))
- {
- ! cs_number (CONTROL1 (s).y - current->y, &charstring_buffer);
- current->y = CONTROL1 (s).y;
- out_point (current, CONTROL2 (s));
- ! cs_number (END_POINT (s).x - current->x, &charstring_buffer);
- current->x = END_POINT (s).x;
- cs_byte (T1_VHCURVETO, &charstring_buffer);
- }
- --- 611,620 ----
- if (epsilon_equal (current->x, CONTROL1 (s).x)
- && epsilon_equal (CONTROL2 (s).y, END_POINT (s).y))
- {
- ! absolute_cs_number (points_to_adobes(CONTROL1 (s).y) -
- points_to_adobes(current->y), &charstring_buffer);
- current->y = CONTROL1 (s).y;
- out_point (current, CONTROL2 (s));
- ! absolute_cs_number (points_to_adobes(END_POINT (s).x) -
- points_to_adobes(current->x), &charstring_buffer);
- current->x = END_POINT (s).x;
- cs_byte (T1_VHCURVETO, &charstring_buffer);
- }
- ***************
- *** 612,621 ****
- else if (epsilon_equal (current->y, CONTROL1 (s).y)
- && epsilon_equal (CONTROL2 (s).x, END_POINT (s).x))
- {
- ! cs_number (CONTROL1 (s).x - current->x, &charstring_buffer);
- current->x = CONTROL1 (s).x;
- out_point (current, CONTROL2 (s));
- ! cs_number (END_POINT (s).y - current->y, &charstring_buffer);
- current->y = END_POINT (s).y;
- cs_byte (T1_HVCURVETO, &charstring_buffer);
- }
- --- 623,632 ----
- else if (epsilon_equal (current->y, CONTROL1 (s).y)
- && epsilon_equal (CONTROL2 (s).x, END_POINT (s).x))
- {
- ! absolute_cs_number (points_to_adobes(CONTROL1 (s).x) -
- points_to_adobes(current->x), &charstring_buffer);
- current->x = CONTROL1 (s).x;
- out_point (current, CONTROL2 (s));
- ! absolute_cs_number (points_to_adobes(END_POINT (s).y) -
- points_to_adobes(current->y), &charstring_buffer);
- current->y = END_POINT (s).y;
- cs_byte (T1_HVCURVETO, &charstring_buffer);
- }
- ***************
- *** 652,657 ****
- --- 663,672 ----
- /* This appends to BUFFER the charstring encoding of the number N,
- assumed to be in printer's points. */
-
- + /*
- + This routine now is not nacessary any more.
- + F. Elfert, 29. Dec 1992
- +
- static void
- cs_number (real n, variable_string *buffer)
- {
- ***************
- *** 659,665 ****
-
- absolute_cs_number (n_in_adobes, buffer);
- }
- !
-
- /* See section 6.2 of the book Adobe Type 1 Font Format. */
-
- --- 674,680 ----
-
- absolute_cs_number (n_in_adobes, buffer);
- }
- ! */
-
- /* See section 6.2 of the book Adobe Type 1 Font Format. */
-
- =============================================================================
-
- I hope this helps you improving these excellent tools.
-
- Happy new Year!
-
- -Fritz (fritz_elfert@wue.maus.de)
-
- PS: Messages in the german .maus domain are restricted to 16k per mail. PLEASE
- do NOT send large listing etc. Thank you!
-
-
- Tschau
- Fritz
-
-