-
Bug
-
Resolution: Unresolved
-
P3
-
openjdk8u
-
x86_64
-
windows_10
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
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