Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8266196

Some font, the size of a chinese char, bold style is smaller then plain style

    XMLWordPrintable

Details

    • 2d
    • x86_64
    • windows_10

    Description

      ADDITIONAL SYSTEM INFORMATION :
      Windows version has this problem.
      If you copy the font to linux, you can find that linux version also has this problem.

      A DESCRIPTION OF THE PROBLEM :
      I draw some chars with graphics. I found if I use some font, the size of a chinese char, bold style is smaller then plain style, and the shape look strange. For example, font is (宋体, 14), char is 泰, I checked size of pixcel on screen:
      plain style: 15x16.
      bold style: 15x15.
      In fact, italic style has same problem.

      REGRESSION : Last worked in version 8

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1, run the code width plain style font.
      2, run the code width plain bold font.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      We hope the char on screen become bold only
      ACTUAL -
      1, the size of char is smaller.
      2, the shape look strange.

      ---------- BEGIN SOURCE ----------
      package taishan;

      import java.awt.Color;
      import java.awt.Font;
      import java.awt.Graphics;

      @SuppressWarnings("serial")
      public class BoldFontFrame extends TFrame
      {
          private final static String FONT_NAME_SONGTI = "宋体";
          private final static int FONT_SIZE = 14;

      private final static char[] TAISHAN = "泰山".toCharArray();

      public BoldFontFrame()
      {
      this.getContentPane().setBackground(Color.WHITE);
      Font testFont = new Font(FONT_NAME_SONGTI, Font.BOLD, FONT_SIZE);
      //testFont = new Font(FONT_NAME_SONGTI, Font.PLAIN, FONT_SIZE);
      this.setFont(testFont);

      }

      @Override
          public void paint(Graphics g)
          {
      super.paint(g);

      g.drawChars(TAISHAN, 0, TAISHAN.length, 30, 30);

          }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      freetypeScaler.c, about 469, comment or remove this code, would resolve this problem:
      !context->doBold

      And if you remove (!context->doItalize), the italic style has no effect. It because freetype doesn't implement this function. I had send my code to freetype, he said vertical italic should be implemented same time:
      1. ftbitmap.h
        FT_EXPORT( FT_Error )
        FT_Bitmap_Italic(
                            FT_Library library,
                            FT_Bitmap* bitmap,
                            FT_Pos xStrength,
                            FT_Pos yStrength );

      2. ftbitmap.c

      #define TAISHAN_FONT_ITALIC_VALUE 0.20F

        FT_EXPORT_DEF( FT_Error )
        FT_Bitmap_Italic( FT_Library library,
                            FT_Bitmap* bitmap,
                            FT_Pos xStrength,
                            FT_Pos yStrength )
        {
          FT_Error error;
          FT_Int pitch;
          FT_UInt y;
          FT_Int xstr, ystr;

          unsigned char* p = NULL;
          int i = 0;
          int newWidth = 0;

          if ( !library )
            return FT_THROW( Invalid_Library_Handle );

          if ( !bitmap || !bitmap->buffer )
            return FT_THROW( Invalid_Argument );

          if ( ( ( FT_PIX_ROUND( xStrength ) >> 6 ) > FT_INT_MAX ) ||
               ( ( FT_PIX_ROUND( yStrength ) >> 6 ) > FT_INT_MAX ) )
            return FT_THROW( Invalid_Argument );

          xstr = (FT_Int)FT_PIX_ROUND( xStrength ) >> 6;
          ystr = (FT_Int)FT_PIX_ROUND( yStrength ) >> 6;

          if ( xstr == 0 && ystr == 0 )
            return FT_Err_Ok;
          else if ( xstr < 0 || ystr < 0 )
            return FT_THROW( Invalid_Argument );

          switch ( bitmap->pixel_mode )
          {
          case FT_PIXEL_MODE_GRAY2:
          case FT_PIXEL_MODE_GRAY4:
            {
              FT_Bitmap tmp;


              /* convert to 8bpp */
              FT_Bitmap_Init( &tmp );
              error = FT_Bitmap_Convert( library, bitmap, &tmp, 1 );
              if ( error )
                return error;

              FT_Bitmap_Done( library, bitmap );
              *bitmap = tmp;
            }
            break;

          case FT_PIXEL_MODE_MONO:
            if ( xstr > 8 )
              xstr = 8;
            break;

          case FT_PIXEL_MODE_LCD:
            xstr *= 3;
            break;

          case FT_PIXEL_MODE_LCD_V:
            ystr *= 3;
            break;

          case FT_PIXEL_MODE_BGRA:
            /* We don't embolden color glyphs. */
            return FT_Err_Ok;
          }

          error = ft_bitmap_assure_buffer( library->memory, bitmap,
                                           (FT_UInt)xstr, (FT_UInt)ystr );
          if ( error )
            return error;

          /* take care of bitmap flow */
          pitch = bitmap->pitch;
          if ( pitch > 0 )
          {
              p = bitmap->buffer;
          }
          else
          {
              pitch = -pitch;
              p = bitmap->buffer + (FT_UInt)pitch * ( bitmap->rows - 1 );
              return error;
          }

          newWidth = (int)(ceil(bitmap->width * (1+TAISHAN_FONT_ITALIC_VALUE)) + (FT_UInt)xstr);
          if (newWidth > (pitch*8))
          {
              newWidth = pitch * 8;
          }

          /* for each row */
          for ( y = 0; y < bitmap->rows; y++ )
          {
            int offset = (int)((bitmap->rows - y) * TAISHAN_FONT_ITALIC_VALUE);
            if (offset == 0)
            {
                break;
            }

            for (i=pitch-1; i>=0; i--)
            {
                p[i] = (p[i] >> offset);
                if (i>0)
                {
                    p[i] = p[i] | (p[i-1] << (8-offset));
                }
            }

            p += bitmap->pitch;
          }

          bitmap->width = newWidth;
          bitmap->rows += (FT_UInt)ystr;
          /* bitmap->pitch = newPitch; */
          /* bitmap->width += (FT_UInt)xstr; */

          return FT_Err_Ok;
        }

      3. ftsynth.c
        FT_EXPORT_DEF( void )
        FT_GlyphSlot_Oblique( FT_GlyphSlot slot )
        {
          FT_Matrix transform;
          FT_Outline* outline;
          FT_Library library;
          FT_Face face;
          FT_Pos xstr, ystr;

          if ( !slot )
            return;

          face = slot->face;
          if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
          {
              library = slot->library;
              
              /* some reasonable strength */
              xstr = FT_MulFix( face->units_per_EM,
                                face->size->metrics.y_scale ) / 24;
              ystr = xstr;
              xstr &= ~63;
              if ( xstr == 0 )
              {
                  xstr = 1 << 6;
              }
              ystr &= ~63;

              /* FT_GlyphSlot_Own_Bitmap( slot ); */
              FT_Bitmap_Italic(library, &slot->bitmap, xstr, ystr );
              return;
          }

          /* we don't touch the advance width */

          /* For italic, simply apply a shear transform, with an angle */
          /* of about 12 degrees. */

          transform.xx = 0x10000L;
          transform.yx = 0x00000L;

          transform.xy = 0x0366AL;
          transform.yy = 0x10000L;
       
          outline = &slot->outline;

          FT_Outline_Transform( outline, &transform );
        }

      FREQUENCY : always


      Attachments

        Activity

          People

            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: