Fop
  1. Fop
  2. FOP-1887

fop misrenders U+002D when using Type 1 fonts

    Details

    • Type: Bug Bug
    • Status: Closed
    • Resolution: Fixed
    • Affects Version/s: trunk
    • Fix Version/s: None
    • Component/s: fonts
    • Labels:
      None
    • Environment:
      Operating System: Linux
      Platform: PC
    • External issue ID:
      50605

      Description

      I have a document that uses U+002D in a variety of situations, including the phrase "troff -mx". Obviously, the U+002D should be flush against the "m". However, when using fop with Nimbus Roman No9 L (the Type 1 Times equivalent from gsfonts) or URW Palladio L (the Type 1 Palatino equivalent), there is a significant gap after the U+002D. This occurs whether the font is bold or not. Hyphenation is also not relevant.

      The problem occurs in 1.0 (and trunk) but does not occur in 0.95. I've used the Apache git bridge to bisect the problem. For git, the problematic commit is 3b4af07609eb6f091ca110d99ba1f63b828222e1; for svn, it is 910445 (at least according to the information the bridge included).

      There are testcases and examples of the misrendering attached to Debian bug 610344 (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=610344). Since Nimbus Roman No9 L is generally the default font for Times on many Linux boxes, this misrendering will likely affect a significant number of users on Linux platforms.

      1. fop-u+002d.patch
        2 kB
        brian m. carlson

        Activity

        Hide
        brian m. carlson added a comment -

        Attachment fop-u+002d.patch has been added with description: Patch to prevent double-mapping

        Show
        brian m. carlson added a comment - Attachment fop-u+002d.patch has been added with description: Patch to prevent double-mapping
        Hide
        brian m. carlson added a comment -

        I've narrowed down the problem to the call to overridePrimaryEncoding on line 422 of Type1FontLoader.java. Commenting this line out seems to solve the problem.

        This function (overridePrimaryEncoding) iterates over the set of metrics and sets a character code for each one based on the mapping passed in. However, two different characters are mapped to 0x2d: U+002D and U+2212. Of course, the metrics for U+2212 are different than those for U+002D; the former is wider than the latter. When layout occurs, the incorrect metrics are used and consequently, a gap occurs.

        I think the sensible thing to do here is not to map U+2212 onto U+002D. Attached is a patch that does exactly that. When we call overridePrimaryEncoding, the encoding is always a single byte. The patch creates an array of 256 elements. When we map a character to a byte value, we store the given character value into the array (indexed by the byte value) and make the mapping. Next time we have a mapping to the same byte value, we do nothing. And by nothing, I mean nothing. We do not map it onto the given byte value (because that breaks things, as I've demonstrated) and we do not map it onto -1 (because then the next glyph is rendered over the top of this one). We simply do nothing.

        Show
        brian m. carlson added a comment - I've narrowed down the problem to the call to overridePrimaryEncoding on line 422 of Type1FontLoader.java. Commenting this line out seems to solve the problem. This function (overridePrimaryEncoding) iterates over the set of metrics and sets a character code for each one based on the mapping passed in. However, two different characters are mapped to 0x2d: U+002D and U+2212. Of course, the metrics for U+2212 are different than those for U+002D; the former is wider than the latter. When layout occurs, the incorrect metrics are used and consequently, a gap occurs. I think the sensible thing to do here is not to map U+2212 onto U+002D. Attached is a patch that does exactly that. When we call overridePrimaryEncoding, the encoding is always a single byte. The patch creates an array of 256 elements. When we map a character to a byte value, we store the given character value into the array (indexed by the byte value) and make the mapping. Next time we have a mapping to the same byte value, we do nothing. And by nothing, I mean nothing. We do not map it onto the given byte value (because that breaks things, as I've demonstrated) and we do not map it onto -1 (because then the next glyph is rendered over the top of this one). We simply do nothing.
        Hide
        Jeremias Maerki added a comment -

        Should be fixed with:
        http://svn.apache.org/viewvc?rev=1142188&view=rev
        http://svn.apache.org/viewvc?rev=1142189&view=rev

        Thanks for taking the time to produce a patch! I've noticed it too late. I've fixed the problem as part of a series of bugfixes in that area and only checked Bugzilla afterwards.

        Show
        Jeremias Maerki added a comment - Should be fixed with: http://svn.apache.org/viewvc?rev=1142188&view=rev http://svn.apache.org/viewvc?rev=1142189&view=rev Thanks for taking the time to produce a patch! I've noticed it too late. I've fixed the problem as part of a series of bugfixes in that area and only checked Bugzilla afterwards.
        Hide
        Glenn Adams added a comment -

        batch transition to closed; if someone wishes to restore one of these to resolved in order to perform a verification step, then feel free to do so

        Show
        Glenn Adams added a comment - batch transition to closed; if someone wishes to restore one of these to resolved in order to perform a verification step, then feel free to do so

          People

          • Assignee:
            fop-dev
            Reporter:
            brian m. carlson
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development