Thread View: gnu.utils.bug
1 messages
1 total messages
Started by Fritz Elfert
Wed, 30 Dec 1992 14:08
bugs in fontutils-0.6/bzrto/ps
Author: Fritz Elfert
Date: Wed, 30 Dec 1992 14:08
Date: Wed, 30 Dec 1992 14:08
331 lines
12848 bytes
12848 bytes
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
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads