gdi32: Move the text metrics cache into the generic font structure.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a89595a259
commit
e0872b6424
|
@ -463,14 +463,20 @@ void free_gdi_font( struct gdi_font *font )
|
|||
if (font->private) font_funcs->destroy_font( font );
|
||||
free_font_handle( font->handle );
|
||||
for (i = 0; i < font->gm_size; i++) HeapFree( GetProcessHeap(), 0, font->gm[i] );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpFamilyName );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpStyleName );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpFaceName );
|
||||
HeapFree( GetProcessHeap(), 0, font->otm.otmpFullName );
|
||||
HeapFree( GetProcessHeap(), 0, font->gm );
|
||||
HeapFree( GetProcessHeap(), 0, font->name );
|
||||
HeapFree( GetProcessHeap(), 0, font );
|
||||
}
|
||||
|
||||
void set_gdi_font_name( struct gdi_font *font, const WCHAR *name )
|
||||
void set_gdi_font_names( struct gdi_font *font, const WCHAR *family_name, const WCHAR *style_name,
|
||||
const WCHAR *full_name )
|
||||
{
|
||||
font->name = strdupW( name );
|
||||
font->otm.otmpFamilyName = (char *)strdupW( family_name );
|
||||
font->otm.otmpStyleName = (char *)strdupW( style_name );
|
||||
font->otm.otmpFaceName = (char *)strdupW( full_name );
|
||||
}
|
||||
|
||||
struct glyph_metrics
|
||||
|
@ -1187,13 +1193,77 @@ static DWORD CDECL font_GetKerningPairs( PHYSDEV dev, DWORD count, KERNINGPAIR *
|
|||
}
|
||||
|
||||
|
||||
static void scale_outline_font_metrics( const struct gdi_font *font, OUTLINETEXTMETRICW *otm )
|
||||
{
|
||||
double scale_x, scale_y;
|
||||
|
||||
if (font->aveWidth)
|
||||
{
|
||||
scale_x = (double)font->aveWidth;
|
||||
scale_x /= (double)font->otm.otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
scale_x = font->scale_y;
|
||||
|
||||
scale_x *= fabs(font->matrix.eM11);
|
||||
scale_y = font->scale_y * fabs(font->matrix.eM22);
|
||||
|
||||
/* Windows scales these values as signed integers even if they are unsigned */
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((int)(x) * (scale_x))
|
||||
#define SCALE_Y(y) (y) = GDI_ROUND((int)(y) * (scale_y))
|
||||
|
||||
SCALE_Y(otm->otmTextMetrics.tmHeight);
|
||||
SCALE_Y(otm->otmTextMetrics.tmAscent);
|
||||
SCALE_Y(otm->otmTextMetrics.tmDescent);
|
||||
SCALE_Y(otm->otmTextMetrics.tmInternalLeading);
|
||||
SCALE_Y(otm->otmTextMetrics.tmExternalLeading);
|
||||
|
||||
SCALE_X(otm->otmTextMetrics.tmOverhang);
|
||||
if (font->fake_bold)
|
||||
{
|
||||
if (!font->scalable) otm->otmTextMetrics.tmOverhang++;
|
||||
otm->otmTextMetrics.tmAveCharWidth++;
|
||||
otm->otmTextMetrics.tmMaxCharWidth++;
|
||||
}
|
||||
SCALE_X(otm->otmTextMetrics.tmAveCharWidth);
|
||||
SCALE_X(otm->otmTextMetrics.tmMaxCharWidth);
|
||||
|
||||
SCALE_Y(otm->otmAscent);
|
||||
SCALE_Y(otm->otmDescent);
|
||||
SCALE_Y(otm->otmLineGap);
|
||||
SCALE_Y(otm->otmsCapEmHeight);
|
||||
SCALE_Y(otm->otmsXHeight);
|
||||
SCALE_Y(otm->otmrcFontBox.top);
|
||||
SCALE_Y(otm->otmrcFontBox.bottom);
|
||||
SCALE_X(otm->otmrcFontBox.left);
|
||||
SCALE_X(otm->otmrcFontBox.right);
|
||||
SCALE_Y(otm->otmMacAscent);
|
||||
SCALE_Y(otm->otmMacDescent);
|
||||
SCALE_Y(otm->otmMacLineGap);
|
||||
SCALE_X(otm->otmptSubscriptSize.x);
|
||||
SCALE_Y(otm->otmptSubscriptSize.y);
|
||||
SCALE_X(otm->otmptSubscriptOffset.x);
|
||||
SCALE_Y(otm->otmptSubscriptOffset.y);
|
||||
SCALE_X(otm->otmptSuperscriptSize.x);
|
||||
SCALE_Y(otm->otmptSuperscriptSize.y);
|
||||
SCALE_X(otm->otmptSuperscriptOffset.x);
|
||||
SCALE_Y(otm->otmptSuperscriptOffset.y);
|
||||
SCALE_Y(otm->otmsStrikeoutSize);
|
||||
SCALE_Y(otm->otmsStrikeoutPosition);
|
||||
SCALE_Y(otm->otmsUnderscoreSize);
|
||||
SCALE_Y(otm->otmsUnderscorePosition);
|
||||
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* font_GetOutlineTextMetrics
|
||||
*/
|
||||
static UINT CDECL font_GetOutlineTextMetrics( PHYSDEV dev, UINT size, OUTLINETEXTMETRICW *metrics )
|
||||
{
|
||||
struct font_physdev *physdev = get_font_dev( dev );
|
||||
UINT ret;
|
||||
UINT ret = 0;
|
||||
|
||||
if (!physdev->font)
|
||||
{
|
||||
|
@ -1204,7 +1274,27 @@ static UINT CDECL font_GetOutlineTextMetrics( PHYSDEV dev, UINT size, OUTLINETEX
|
|||
if (!physdev->font->scalable) return 0;
|
||||
|
||||
EnterCriticalSection( &font_cs );
|
||||
ret = font_funcs->pGetOutlineTextMetrics( physdev->font, size, metrics );
|
||||
if (font_funcs->set_outline_text_metrics( physdev->font ))
|
||||
{
|
||||
ret = physdev->font->otm.otmSize;
|
||||
if (metrics && size >= physdev->font->otm.otmSize)
|
||||
{
|
||||
WCHAR *ptr = (WCHAR *)(metrics + 1);
|
||||
*metrics = physdev->font->otm;
|
||||
metrics->otmpFamilyName = (char *)ptr - (ULONG_PTR)metrics;
|
||||
strcpyW( ptr, (WCHAR *)physdev->font->otm.otmpFamilyName );
|
||||
ptr += strlenW(ptr) + 1;
|
||||
metrics->otmpStyleName = (char *)ptr - (ULONG_PTR)metrics;
|
||||
strcpyW( ptr, (WCHAR *)physdev->font->otm.otmpStyleName );
|
||||
ptr += strlenW(ptr) + 1;
|
||||
metrics->otmpFaceName = (char *)ptr - (ULONG_PTR)metrics;
|
||||
strcpyW( ptr, (WCHAR *)physdev->font->otm.otmpFaceName );
|
||||
ptr += strlenW(ptr) + 1;
|
||||
metrics->otmpFullName = (char *)ptr - (ULONG_PTR)metrics;
|
||||
strcpyW( ptr, (WCHAR *)physdev->font->otm.otmpFullName );
|
||||
scale_outline_font_metrics( physdev->font, metrics );
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection( &font_cs );
|
||||
return ret;
|
||||
}
|
||||
|
@ -1301,23 +1391,68 @@ static INT CDECL font_GetTextFace( PHYSDEV dev, INT count, WCHAR *str )
|
|||
dev = GET_NEXT_PHYSDEV( dev, pGetTextFace );
|
||||
return dev->funcs->pGetTextFace( dev, count, str );
|
||||
}
|
||||
len = strlenW( physdev->font->name ) + 1;
|
||||
len = strlenW( get_gdi_font_name(physdev->font) ) + 1;
|
||||
if (str)
|
||||
{
|
||||
lstrcpynW( str, physdev->font->name, count );
|
||||
lstrcpynW( str, get_gdi_font_name(physdev->font), count );
|
||||
len = min( count, len );
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
static void scale_font_metrics( struct gdi_font *font, TEXTMETRICW *tm )
|
||||
{
|
||||
double scale_x, scale_y;
|
||||
|
||||
/* Make sure that the font has sane width/height ratio */
|
||||
if (font->aveWidth && (font->aveWidth + tm->tmHeight - 1) / tm->tmHeight > 100)
|
||||
{
|
||||
WARN( "Ignoring too large font->aveWidth %d\n", font->aveWidth );
|
||||
font->aveWidth = 0;
|
||||
}
|
||||
|
||||
if (font->aveWidth)
|
||||
{
|
||||
scale_x = (double)font->aveWidth;
|
||||
scale_x /= (double)font->otm.otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
scale_x = font->scale_y;
|
||||
|
||||
scale_x *= fabs(font->matrix.eM11);
|
||||
scale_y = font->scale_y * fabs(font->matrix.eM22);
|
||||
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((x) * scale_x)
|
||||
#define SCALE_Y(y) (y) = GDI_ROUND((y) * scale_y)
|
||||
|
||||
SCALE_Y(tm->tmHeight);
|
||||
SCALE_Y(tm->tmAscent);
|
||||
SCALE_Y(tm->tmDescent);
|
||||
SCALE_Y(tm->tmInternalLeading);
|
||||
SCALE_Y(tm->tmExternalLeading);
|
||||
|
||||
SCALE_X(tm->tmOverhang);
|
||||
if (font->fake_bold)
|
||||
{
|
||||
if (!font->scalable) tm->tmOverhang++;
|
||||
tm->tmAveCharWidth++;
|
||||
tm->tmMaxCharWidth++;
|
||||
}
|
||||
SCALE_X(tm->tmAveCharWidth);
|
||||
SCALE_X(tm->tmMaxCharWidth);
|
||||
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* font_GetTextMetrics
|
||||
*/
|
||||
static BOOL CDECL font_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
|
||||
{
|
||||
struct font_physdev *physdev = get_font_dev( dev );
|
||||
BOOL ret;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!physdev->font)
|
||||
{
|
||||
|
@ -1326,7 +1461,13 @@ static BOOL CDECL font_GetTextMetrics( PHYSDEV dev, TEXTMETRICW *metrics )
|
|||
}
|
||||
|
||||
EnterCriticalSection( &font_cs );
|
||||
ret = font_funcs->pGetTextMetrics( physdev->font, metrics );
|
||||
if (font_funcs->set_outline_text_metrics( physdev->font ) ||
|
||||
font_funcs->set_bitmap_text_metrics( physdev->font ))
|
||||
{
|
||||
*metrics = physdev->font->otm.otmTextMetrics;
|
||||
scale_font_metrics( physdev->font, metrics );
|
||||
ret = TRUE;
|
||||
}
|
||||
LeaveCriticalSection( &font_cs );
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -302,7 +302,6 @@ typedef struct {
|
|||
|
||||
struct tagGdiFont {
|
||||
struct gdi_font *gdi_font;
|
||||
OUTLINETEXTMETRICW *potm;
|
||||
DWORD total_kern_pairs;
|
||||
KERNINGPAIR *kern_pairs;
|
||||
struct list child_fonts;
|
||||
|
@ -457,9 +456,8 @@ static const WCHAR szDefaultFallbackLink[] = {'M','i','c','r','o','s','o','f','t
|
|||
|
||||
static BOOL map_font_family(const WCHAR *orig, const WCHAR *repl);
|
||||
static BOOL get_glyph_index_linked(GdiFont *font, UINT c, GdiFont **linked_font, FT_UInt *glyph, BOOL *vert);
|
||||
static BOOL get_outline_text_metrics(GdiFont *font);
|
||||
static BOOL get_bitmap_text_metrics(GdiFont *font);
|
||||
static BOOL get_text_metrics(GdiFont *font, LPTEXTMETRICW ptm);
|
||||
static BOOL CDECL freetype_set_outline_text_metrics( struct gdi_font *font );
|
||||
static BOOL CDECL freetype_set_bitmap_text_metrics( struct gdi_font *font );
|
||||
static void remove_face_from_cache( Face *face );
|
||||
|
||||
static const WCHAR system_link[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
|
||||
|
@ -4023,7 +4021,6 @@ static UINT get_nearest_charset(const WCHAR *family_name, Face *face, UINT *cp)
|
|||
static BOOL CDECL freetype_alloc_font( struct gdi_font *font )
|
||||
{
|
||||
GdiFont *ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret));
|
||||
ret->potm = NULL;
|
||||
ret->total_kern_pairs = (DWORD)-1;
|
||||
ret->kern_pairs = NULL;
|
||||
list_init(&ret->child_fonts);
|
||||
|
@ -4052,7 +4049,6 @@ static void CDECL freetype_destroy_font( struct gdi_font *gdi_font )
|
|||
if (font->ft_face) pFT_Done_Face(font->ft_face);
|
||||
if (font->mapping) unmap_font_file( font->mapping );
|
||||
HeapFree(GetProcessHeap(), 0, font->kern_pairs);
|
||||
HeapFree(GetProcessHeap(), 0, font->potm);
|
||||
HeapFree(GetProcessHeap(), 0, font->GSUB_Table);
|
||||
HeapFree(GetProcessHeap(), 0, font);
|
||||
}
|
||||
|
@ -4275,10 +4271,10 @@ static BOOL create_child_font_list(GdiFont *font)
|
|||
SYSTEM_LINKS *font_link;
|
||||
CHILD_FONT *font_link_entry, *new_child;
|
||||
FontSubst *psub;
|
||||
WCHAR* font_name;
|
||||
const WCHAR* font_name;
|
||||
|
||||
psub = get_font_subst(&font_subst_list, gdi_font->name, -1);
|
||||
font_name = psub ? psub->to.name : gdi_font->name;
|
||||
psub = get_font_subst(&font_subst_list, get_gdi_font_name(gdi_font), -1);
|
||||
font_name = psub ? psub->to.name : get_gdi_font_name(gdi_font);
|
||||
font_link = find_font_link(font_name);
|
||||
if (font_link != NULL)
|
||||
{
|
||||
|
@ -5046,7 +5042,8 @@ found_face:
|
|||
|
||||
pick_charmap( ret->ft_face, gdi_font->charset );
|
||||
|
||||
set_gdi_font_name( gdi_font, psub ? psub->from.name : family->family_name );
|
||||
set_gdi_font_names( gdi_font, psub ? psub->from.name : family->family_name,
|
||||
face->style_name, face->full_name );
|
||||
create_child_font_list(ret);
|
||||
|
||||
if (face->flags & ADDFONT_VERTICAL_FONT) /* We need to try to load the GSUB table */
|
||||
|
@ -5257,30 +5254,24 @@ static void GetEnumStructs(Face *face, const WCHAR *family_name, LPENUMLOGFONTEX
|
|||
return;
|
||||
}
|
||||
|
||||
set_gdi_font_name( gdi_font, family_name );
|
||||
set_gdi_font_names( gdi_font, family_name, face->style_name, face->full_name );
|
||||
gdi_font->ntmFlags = face->ntmFlags;
|
||||
|
||||
if (get_outline_text_metrics(font))
|
||||
if (freetype_set_outline_text_metrics(gdi_font))
|
||||
{
|
||||
memcpy(&pntm->ntmTm, &font->potm->otmTextMetrics, sizeof(TEXTMETRICW));
|
||||
memcpy(&pntm->ntmTm, &gdi_font->otm.otmTextMetrics, sizeof(TEXTMETRICW));
|
||||
|
||||
pntm->ntmTm.ntmSizeEM = font->potm->otmEMSquare;
|
||||
pntm->ntmTm.ntmSizeEM = gdi_font->otm.otmEMSquare;
|
||||
pntm->ntmTm.ntmCellHeight = gdi_font->ntmCellHeight;
|
||||
pntm->ntmTm.ntmAvgWidth = gdi_font->ntmAvgWidth;
|
||||
|
||||
lstrcpynW(pelf->elfLogFont.lfFaceName,
|
||||
(WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpFamilyName),
|
||||
LF_FACESIZE);
|
||||
lstrcpynW(pelf->elfFullName,
|
||||
(WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpFaceName),
|
||||
LF_FULLFACESIZE);
|
||||
lstrcpynW(pelf->elfStyle,
|
||||
(WCHAR*)((char*)font->potm + (ULONG_PTR)font->potm->otmpStyleName),
|
||||
LF_FACESIZE);
|
||||
lstrcpynW(pelf->elfLogFont.lfFaceName, (WCHAR *)gdi_font->otm.otmpFamilyName, LF_FACESIZE);
|
||||
lstrcpynW(pelf->elfFullName, (WCHAR *)gdi_font->otm.otmpFaceName, LF_FULLFACESIZE);
|
||||
lstrcpynW(pelf->elfStyle, (WCHAR *)gdi_font->otm.otmpStyleName, LF_FACESIZE);
|
||||
}
|
||||
else
|
||||
else if (freetype_set_bitmap_text_metrics( gdi_font ))
|
||||
{
|
||||
get_text_metrics(font, (TEXTMETRICW *)&pntm->ntmTm);
|
||||
memcpy(&pntm->ntmTm, &gdi_font->otm.otmTextMetrics, sizeof(TEXTMETRICW));
|
||||
|
||||
pntm->ntmTm.ntmSizeEM = pntm->ntmTm.tmHeight - pntm->ntmTm.tmInternalLeading;
|
||||
pntm->ntmTm.ntmCellHeight = pntm->ntmTm.tmHeight;
|
||||
|
@ -5741,10 +5732,9 @@ enum matrices_index
|
|||
matrix_unrotated
|
||||
};
|
||||
|
||||
static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *user_transform,
|
||||
static BOOL get_transform_matrices( struct gdi_font *font, BOOL vertical, const MAT2 *user_transform,
|
||||
FT_Matrix matrices[3] )
|
||||
{
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
static const FT_Matrix identity_mat = { (1 << 16), 0, 0, (1 << 16) };
|
||||
BOOL needs_transform = FALSE;
|
||||
double width_ratio;
|
||||
|
@ -5753,32 +5743,30 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
|
|||
matrices[matrix_unrotated] = identity_mat;
|
||||
|
||||
/* Scaling factor */
|
||||
if (gdi_font->aveWidth)
|
||||
if (font->aveWidth)
|
||||
{
|
||||
TEXTMETRICW tm;
|
||||
get_text_metrics( font, &tm );
|
||||
|
||||
width_ratio = (double)gdi_font->aveWidth;
|
||||
width_ratio /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||
if (!freetype_set_outline_text_metrics( font )) freetype_set_bitmap_text_metrics( font );
|
||||
width_ratio = (double)font->aveWidth;
|
||||
width_ratio /= (double)font->otm.otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
width_ratio = gdi_font->scale_y;
|
||||
width_ratio = font->scale_y;
|
||||
|
||||
/* Scaling transform */
|
||||
if (width_ratio != 1.0 || gdi_font->scale_y != 1.0)
|
||||
if (width_ratio != 1.0 || font->scale_y != 1.0)
|
||||
{
|
||||
FT_Matrix scale_mat;
|
||||
scale_mat.xx = FT_FixedFromFloat( width_ratio );
|
||||
scale_mat.xy = 0;
|
||||
scale_mat.yx = 0;
|
||||
scale_mat.yy = FT_FixedFromFloat( gdi_font->scale_y );
|
||||
scale_mat.yy = FT_FixedFromFloat( font->scale_y );
|
||||
|
||||
pFT_Matrix_Multiply( &scale_mat, &matrices[matrix_unrotated] );
|
||||
needs_transform = TRUE;
|
||||
}
|
||||
|
||||
/* Slant transform */
|
||||
if (gdi_font->fake_italic)
|
||||
if (font->fake_italic)
|
||||
{
|
||||
FT_Matrix slant_mat;
|
||||
slant_mat.xx = (1 << 16);
|
||||
|
@ -5792,12 +5780,12 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
|
|||
|
||||
/* Rotation transform */
|
||||
matrices[matrix_hori] = matrices[matrix_unrotated];
|
||||
if (gdi_font->scalable && gdi_font->lf.lfOrientation % 3600)
|
||||
if (font->scalable && font->lf.lfOrientation % 3600)
|
||||
{
|
||||
FT_Matrix rotation_mat;
|
||||
FT_Vector angle;
|
||||
|
||||
pFT_Vector_Unit( &angle, MulDiv( 1 << 16, gdi_font->lf.lfOrientation, 10 ) );
|
||||
pFT_Vector_Unit( &angle, MulDiv( 1 << 16, font->lf.lfOrientation, 10 ) );
|
||||
rotation_mat.xx = angle.x;
|
||||
rotation_mat.xy = -angle.y;
|
||||
rotation_mat.yx = angle.y;
|
||||
|
@ -5817,13 +5805,13 @@ static BOOL get_transform_matrices( GdiFont *font, BOOL vertical, const MAT2 *us
|
|||
}
|
||||
|
||||
/* World transform */
|
||||
if (!is_identity_FMAT2( &gdi_font->matrix ))
|
||||
if (!is_identity_FMAT2( &font->matrix ))
|
||||
{
|
||||
FT_Matrix world_mat;
|
||||
world_mat.xx = FT_FixedFromFloat( gdi_font->matrix.eM11 );
|
||||
world_mat.xy = -FT_FixedFromFloat( gdi_font->matrix.eM21 );
|
||||
world_mat.yx = -FT_FixedFromFloat( gdi_font->matrix.eM12 );
|
||||
world_mat.yy = FT_FixedFromFloat( gdi_font->matrix.eM22 );
|
||||
world_mat.xx = FT_FixedFromFloat( font->matrix.eM11 );
|
||||
world_mat.xy = -FT_FixedFromFloat( font->matrix.eM21 );
|
||||
world_mat.yx = -FT_FixedFromFloat( font->matrix.eM12 );
|
||||
world_mat.yy = FT_FixedFromFloat( font->matrix.eM22 );
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
pFT_Matrix_Multiply( &world_mat, &matrices[i] );
|
||||
|
@ -5897,12 +5885,10 @@ static BOOL check_unicode_tategaki(WCHAR uchar)
|
|||
return (orientation == 1 || orientation == 3);
|
||||
}
|
||||
|
||||
static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font,
|
||||
static FT_Vector get_advance_metric(struct gdi_font *incoming_font, struct gdi_font *font,
|
||||
const FT_Glyph_Metrics *metrics,
|
||||
const FT_Matrix *transMat, BOOL vertical_metrics)
|
||||
{
|
||||
struct gdi_font *incoming_gdi_font = incoming_font->gdi_font;
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
FT_Vector adv;
|
||||
FT_Fixed base_advance, em_scale = 0;
|
||||
BOOL fixed_pitch_full = FALSE;
|
||||
|
@ -5919,16 +5905,15 @@ static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font,
|
|||
they have double halfwidth character width. E.g. if the font is 19 ppem,
|
||||
we return 20 (not 19) for fullwidth characters as we return 10 for
|
||||
halfwidth characters. */
|
||||
if(incoming_gdi_font->scalable &&
|
||||
(incoming_font->potm || get_outline_text_metrics(incoming_font)) &&
|
||||
!(incoming_font->potm->otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
|
||||
if (freetype_set_outline_text_metrics(incoming_font) &&
|
||||
!(incoming_font->otm.otmTextMetrics.tmPitchAndFamily & TMPF_FIXED_PITCH)) {
|
||||
UINT avg_advance;
|
||||
em_scale = MulDiv(incoming_gdi_font->ppem, 1 << 16,
|
||||
incoming_font->ft_face->units_per_EM);
|
||||
avg_advance = pFT_MulFix(incoming_gdi_font->ntmAvgWidth, em_scale);
|
||||
em_scale = MulDiv(incoming_font->ppem, 1 << 16,
|
||||
get_font_ptr(incoming_font)->ft_face->units_per_EM);
|
||||
avg_advance = pFT_MulFix(incoming_font->ntmAvgWidth, em_scale);
|
||||
fixed_pitch_full = (avg_advance > 0 &&
|
||||
(base_advance + 63) >> 6 ==
|
||||
pFT_MulFix(incoming_gdi_font->ntmAvgWidth*2, em_scale));
|
||||
pFT_MulFix(incoming_font->ntmAvgWidth*2, em_scale));
|
||||
if (fixed_pitch_full && !transMat)
|
||||
adv.x = (avg_advance * 2) << 6;
|
||||
}
|
||||
|
@ -5937,14 +5922,14 @@ static FT_Vector get_advance_metric(GdiFont *incoming_font, GdiFont *font,
|
|||
pFT_Vector_Transform(&adv, transMat);
|
||||
if (fixed_pitch_full && adv.y == 0) {
|
||||
FT_Vector vec;
|
||||
vec.x = incoming_gdi_font->ntmAvgWidth;
|
||||
vec.x = incoming_font->ntmAvgWidth;
|
||||
vec.y = 0;
|
||||
pFT_Vector_Transform(&vec, transMat);
|
||||
adv.x = (pFT_MulFix(vec.x, em_scale) * 2) << 6;
|
||||
}
|
||||
}
|
||||
|
||||
if (gdi_font->fake_bold) {
|
||||
if (font->fake_bold) {
|
||||
if (!transMat)
|
||||
adv.x += 1 << 6;
|
||||
else {
|
||||
|
@ -6010,7 +5995,7 @@ static FT_BBox get_transformed_bbox( const FT_Glyph_Metrics *metrics,
|
|||
return bbox;
|
||||
}
|
||||
|
||||
static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
|
||||
static void compute_metrics( struct gdi_font *incoming_font, struct gdi_font *font,
|
||||
FT_BBox bbox, const FT_Glyph_Metrics *metrics,
|
||||
BOOL vertical, BOOL vertical_metrics,
|
||||
BOOL needs_transform, const FT_Matrix matrices[3],
|
||||
|
@ -6032,14 +6017,14 @@ static void compute_metrics( GdiFont *incoming_font, GdiFont *font,
|
|||
{
|
||||
FT_Pos lsb;
|
||||
|
||||
if (vertical && (font->potm || get_outline_text_metrics( font )))
|
||||
if (vertical && freetype_set_outline_text_metrics( font ))
|
||||
{
|
||||
if (vertical_metrics)
|
||||
lsb = metrics->horiBearingY + metrics->vertBearingY;
|
||||
else
|
||||
lsb = metrics->vertAdvance + (font->potm->otmDescent << 6);
|
||||
lsb = metrics->vertAdvance + (font->otm.otmDescent << 6);
|
||||
vec.x = lsb;
|
||||
vec.y = font->potm->otmDescent << 6;
|
||||
vec.y = font->otm.otmDescent << 6;
|
||||
TRACE( "Vec %ld,%ld\n", vec.x>>6, vec.y>>6 );
|
||||
pFT_Vector_Transform( &vec, &matrices[matrix_hori] );
|
||||
origin.x = (vec.x + bbox.xMin) & -64;
|
||||
|
@ -6634,7 +6619,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
|
|||
FT_Int load_flags = get_load_flags(format);
|
||||
FT_Matrix matrices[3];
|
||||
BOOL needsTransform = FALSE;
|
||||
BOOL tategaki = (gdi_font->name[0] == '@');
|
||||
BOOL tategaki = (*get_gdi_font_name(gdi_font) == '@');
|
||||
BOOL vertical_metrics;
|
||||
|
||||
TRACE("%p, %04x, %08x, %p, %08x, %p, %p\n", font, glyph, format, lpgm,
|
||||
|
@ -6671,7 +6656,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
|
|||
get_gdi_font_glyph_metrics( gdi_font, glyph_index, lpgm, abc ))
|
||||
return 1; /* FIXME */
|
||||
|
||||
needsTransform = get_transform_matrices( font, tategaki, lpmat, matrices );
|
||||
needsTransform = get_transform_matrices( gdi_font, tategaki, lpmat, matrices );
|
||||
|
||||
vertical_metrics = (tategaki && FT_HAS_VERTICAL(ft_face));
|
||||
/* there is a freetype bug where vertical metrics are only
|
||||
|
@ -6704,9 +6689,9 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
|
|||
/* Some poorly-created fonts contain glyphs that exceed the boundaries set
|
||||
* by the text metrics. The proper behavior is to clip the glyph metrics to
|
||||
* fit within the maximums specified in the text metrics. */
|
||||
if(incoming_font->potm || get_outline_text_metrics(incoming_font) ||
|
||||
get_bitmap_text_metrics(incoming_font)) {
|
||||
TEXTMETRICW *ptm = &incoming_font->potm->otmTextMetrics;
|
||||
if (freetype_set_outline_text_metrics(incoming_gdi_font) ||
|
||||
freetype_set_bitmap_text_metrics(incoming_gdi_font)) {
|
||||
TEXTMETRICW *ptm = &incoming_gdi_font->otm.otmTextMetrics;
|
||||
INT top = min( metrics.horiBearingY, ptm->tmAscent << 6 );
|
||||
INT bottom = max( metrics.horiBearingY - metrics.height, -(ptm->tmDescent << 6) );
|
||||
metrics.horiBearingY = top;
|
||||
|
@ -6717,7 +6702,7 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
|
|||
}
|
||||
|
||||
bbox = get_transformed_bbox( &metrics, needsTransform, matrices );
|
||||
compute_metrics( incoming_font, font, bbox, &metrics,
|
||||
compute_metrics( incoming_gdi_font, gdi_font, bbox, &metrics,
|
||||
tategaki, vertical_metrics, needsTransform, matrices,
|
||||
&gm, abc );
|
||||
|
||||
|
@ -6809,16 +6794,18 @@ static DWORD CDECL freetype_get_glyph_outline( struct gdi_font *incoming_gdi_fon
|
|||
return needed;
|
||||
}
|
||||
|
||||
static BOOL get_bitmap_text_metrics(GdiFont *font)
|
||||
/*************************************************************
|
||||
* freetype_set_bitmap_text_metrics
|
||||
*/
|
||||
static BOOL CDECL freetype_set_bitmap_text_metrics( struct gdi_font *font )
|
||||
{
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
FT_Face ft_face = font->ft_face;
|
||||
FT_Face ft_face = get_font_ptr( font )->ft_face;
|
||||
FT_WinFNT_HeaderRec winfnt_header;
|
||||
const DWORD size = offsetof(OUTLINETEXTMETRICW, otmFiller);
|
||||
font->potm = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
font->potm->otmSize = size;
|
||||
|
||||
#define TM font->potm->otmTextMetrics
|
||||
if (font->otm.otmSize) return TRUE; /* already set */
|
||||
font->otm.otmSize = offsetof( OUTLINETEXTMETRICW, otmFiller );
|
||||
|
||||
#define TM font->otm.otmTextMetrics
|
||||
if(!pFT_Get_WinFNT_Header(ft_face, &winfnt_header))
|
||||
{
|
||||
TM.tmHeight = winfnt_header.pixel_height;
|
||||
|
@ -6860,12 +6847,12 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
|
|||
TM.tmItalic = ft_face->style_flags & FT_STYLE_FLAG_ITALIC ? 1 : 0;
|
||||
/* NB inverted meaning of TMPF_FIXED_PITCH */
|
||||
TM.tmPitchAndFamily = FT_IS_FIXED_WIDTH(ft_face) ? 0 : TMPF_FIXED_PITCH;
|
||||
TM.tmCharSet = gdi_font->charset;
|
||||
TM.tmCharSet = font->charset;
|
||||
}
|
||||
TM.tmUnderlined = gdi_font->lf.lfUnderline ? 0xff : 0;
|
||||
TM.tmStruckOut = gdi_font->lf.lfStrikeOut ? 0xff : 0;
|
||||
TM.tmUnderlined = font->lf.lfUnderline ? 0xff : 0;
|
||||
TM.tmStruckOut = font->lf.lfStrikeOut ? 0xff : 0;
|
||||
|
||||
if(gdi_font->fake_bold)
|
||||
if(font->fake_bold)
|
||||
TM.tmWeight = FW_BOLD;
|
||||
#undef TM
|
||||
|
||||
|
@ -6873,119 +6860,6 @@ static BOOL get_bitmap_text_metrics(GdiFont *font)
|
|||
}
|
||||
|
||||
|
||||
static void scale_font_metrics(const GdiFont *font, LPTEXTMETRICW ptm)
|
||||
{
|
||||
const struct gdi_font *gdi_font = font->gdi_font;
|
||||
double scale_x, scale_y;
|
||||
|
||||
if (gdi_font->aveWidth)
|
||||
{
|
||||
scale_x = (double)gdi_font->aveWidth;
|
||||
scale_x /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
scale_x = gdi_font->scale_y;
|
||||
|
||||
scale_x *= fabs(gdi_font->matrix.eM11);
|
||||
scale_y = gdi_font->scale_y * fabs(gdi_font->matrix.eM22);
|
||||
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((double)(x) * (scale_x))
|
||||
#define SCALE_Y(y) (y) = GDI_ROUND((double)(y) * (scale_y))
|
||||
|
||||
SCALE_Y(ptm->tmHeight);
|
||||
SCALE_Y(ptm->tmAscent);
|
||||
SCALE_Y(ptm->tmDescent);
|
||||
SCALE_Y(ptm->tmInternalLeading);
|
||||
SCALE_Y(ptm->tmExternalLeading);
|
||||
|
||||
SCALE_X(ptm->tmOverhang);
|
||||
if(gdi_font->fake_bold)
|
||||
{
|
||||
if(!gdi_font->scalable)
|
||||
ptm->tmOverhang++;
|
||||
ptm->tmAveCharWidth++;
|
||||
ptm->tmMaxCharWidth++;
|
||||
}
|
||||
SCALE_X(ptm->tmAveCharWidth);
|
||||
SCALE_X(ptm->tmMaxCharWidth);
|
||||
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
}
|
||||
|
||||
static void scale_outline_font_metrics(const GdiFont *font, OUTLINETEXTMETRICW *potm)
|
||||
{
|
||||
const struct gdi_font *gdi_font = font->gdi_font;
|
||||
double scale_x, scale_y;
|
||||
|
||||
if (gdi_font->aveWidth)
|
||||
{
|
||||
scale_x = (double)gdi_font->aveWidth;
|
||||
scale_x /= (double)font->potm->otmTextMetrics.tmAveCharWidth;
|
||||
}
|
||||
else
|
||||
scale_x = gdi_font->scale_y;
|
||||
|
||||
scale_x *= fabs(gdi_font->matrix.eM11);
|
||||
scale_y = gdi_font->scale_y * fabs(gdi_font->matrix.eM22);
|
||||
|
||||
scale_font_metrics(font, &potm->otmTextMetrics);
|
||||
|
||||
/* Windows scales these values as signed integers even if they are unsigned */
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((int)(x) * (scale_x))
|
||||
#define SCALE_Y(y) (y) = GDI_ROUND((int)(y) * (scale_y))
|
||||
|
||||
SCALE_Y(potm->otmAscent);
|
||||
SCALE_Y(potm->otmDescent);
|
||||
SCALE_Y(potm->otmLineGap);
|
||||
SCALE_Y(potm->otmsCapEmHeight);
|
||||
SCALE_Y(potm->otmsXHeight);
|
||||
SCALE_Y(potm->otmrcFontBox.top);
|
||||
SCALE_Y(potm->otmrcFontBox.bottom);
|
||||
SCALE_X(potm->otmrcFontBox.left);
|
||||
SCALE_X(potm->otmrcFontBox.right);
|
||||
SCALE_Y(potm->otmMacAscent);
|
||||
SCALE_Y(potm->otmMacDescent);
|
||||
SCALE_Y(potm->otmMacLineGap);
|
||||
SCALE_X(potm->otmptSubscriptSize.x);
|
||||
SCALE_Y(potm->otmptSubscriptSize.y);
|
||||
SCALE_X(potm->otmptSubscriptOffset.x);
|
||||
SCALE_Y(potm->otmptSubscriptOffset.y);
|
||||
SCALE_X(potm->otmptSuperscriptSize.x);
|
||||
SCALE_Y(potm->otmptSuperscriptSize.y);
|
||||
SCALE_X(potm->otmptSuperscriptOffset.x);
|
||||
SCALE_Y(potm->otmptSuperscriptOffset.y);
|
||||
SCALE_Y(potm->otmsStrikeoutSize);
|
||||
SCALE_Y(potm->otmsStrikeoutPosition);
|
||||
SCALE_Y(potm->otmsUnderscoreSize);
|
||||
SCALE_Y(potm->otmsUnderscorePosition);
|
||||
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
}
|
||||
|
||||
static BOOL get_text_metrics(GdiFont *font, LPTEXTMETRICW ptm)
|
||||
{
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
if(!font->potm)
|
||||
{
|
||||
if (!get_outline_text_metrics(font) && !get_bitmap_text_metrics(font)) return FALSE;
|
||||
|
||||
/* Make sure that the font has sane width/height ratio */
|
||||
if (gdi_font->aveWidth)
|
||||
{
|
||||
if ((gdi_font->aveWidth + font->potm->otmTextMetrics.tmHeight - 1) / font->potm->otmTextMetrics.tmHeight > 100)
|
||||
{
|
||||
WARN("Ignoring too large font->aveWidth %d\n", gdi_font->aveWidth);
|
||||
gdi_font->aveWidth = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptm = font->potm->otmTextMetrics;
|
||||
scale_font_metrics(font, ptm);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL face_has_symbol_charmap(FT_Face ft_face)
|
||||
{
|
||||
int i;
|
||||
|
@ -6998,74 +6872,51 @@ static BOOL face_has_symbol_charmap(FT_Face ft_face)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL get_outline_text_metrics(GdiFont *font)
|
||||
/*************************************************************
|
||||
* freetype_set_outline_text_metrics
|
||||
*/
|
||||
static BOOL CDECL freetype_set_outline_text_metrics( struct gdi_font *font )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
FT_Face ft_face = font->ft_face;
|
||||
struct gdi_font *gdi_font = font->gdi_font;
|
||||
UINT needed, lenfam, lensty, lenface, lenfull;
|
||||
FT_Face ft_face = get_font_ptr( font )->ft_face;
|
||||
UINT needed;
|
||||
TT_OS2 *pOS2;
|
||||
TT_HoriHeader *pHori;
|
||||
TT_Postscript *pPost;
|
||||
FT_Fixed em_scale;
|
||||
WCHAR *family_nameW, *style_nameW, *face_nameW, *full_nameW;
|
||||
char *cp;
|
||||
INT ascent, descent;
|
||||
USHORT windescent;
|
||||
|
||||
TRACE("font=%p\n", font);
|
||||
|
||||
if(!FT_IS_SCALABLE(ft_face))
|
||||
return FALSE;
|
||||
if (!font->scalable) return FALSE;
|
||||
if (font->otm.otmSize) return TRUE; /* already set */
|
||||
|
||||
needed = sizeof(*font->potm);
|
||||
|
||||
lenfam = (strlenW(gdi_font->name) + 1) * sizeof(WCHAR);
|
||||
family_nameW = strdupW(gdi_font->name);
|
||||
|
||||
style_nameW = ft_face_get_style_name( ft_face, GetSystemDefaultLangID() );
|
||||
lensty = (strlenW(style_nameW) + 1) * sizeof(WCHAR);
|
||||
|
||||
face_nameW = ft_face_get_full_name( ft_face, GetSystemDefaultLangID() );
|
||||
if (gdi_font->name[0] == '@') face_nameW = get_vertical_name( face_nameW );
|
||||
lenface = (strlenW(face_nameW) + 1) * sizeof(WCHAR);
|
||||
|
||||
full_nameW = get_face_name( ft_face, TT_NAME_ID_UNIQUE_ID, GetSystemDefaultLangID() );
|
||||
if (!full_nameW)
|
||||
/* note: we store actual pointers in the names instead of offsets,
|
||||
they are fixed up when returned to the app */
|
||||
if (!(font->otm.otmpFullName = (char *)get_face_name( ft_face, TT_NAME_ID_UNIQUE_ID,
|
||||
GetSystemDefaultLangID() )))
|
||||
{
|
||||
static const WCHAR fake_nameW[] = {'f','a','k','e',' ','n','a','m','e', 0};
|
||||
FIXME("failed to read full_nameW for font %s!\n", wine_dbgstr_w(gdi_font->name));
|
||||
full_nameW = strdupW(fake_nameW);
|
||||
FIXME("failed to read full_nameW for font %s!\n", wine_dbgstr_w(get_gdi_font_name(font)));
|
||||
font->otm.otmpFullName = (char *)strdupW(fake_nameW);
|
||||
}
|
||||
lenfull = (strlenW(full_nameW) + 1) * sizeof(WCHAR);
|
||||
needed = sizeof(font->otm) + (strlenW( (WCHAR *)font->otm.otmpFamilyName ) + 1 +
|
||||
strlenW( (WCHAR *)font->otm.otmpStyleName ) + 1 +
|
||||
strlenW( (WCHAR *)font->otm.otmpFaceName ) + 1 +
|
||||
strlenW( (WCHAR *)font->otm.otmpFullName ) + 1) * sizeof(WCHAR);
|
||||
|
||||
/* These names should be read from the TT name table */
|
||||
|
||||
/* length of otmpFamilyName */
|
||||
needed += lenfam;
|
||||
|
||||
/* length of otmpFaceName */
|
||||
needed += lenface;
|
||||
|
||||
/* length of otmpStyleName */
|
||||
needed += lensty;
|
||||
|
||||
/* length of otmpFullName */
|
||||
needed += lenfull;
|
||||
|
||||
|
||||
em_scale = (FT_Fixed)MulDiv(gdi_font->ppem, 1 << 16, ft_face->units_per_EM);
|
||||
em_scale = (FT_Fixed)MulDiv(font->ppem, 1 << 16, ft_face->units_per_EM);
|
||||
|
||||
pOS2 = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
|
||||
if(!pOS2) {
|
||||
FIXME("Can't find OS/2 table - not TT font?\n");
|
||||
goto end;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pHori = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_hhea);
|
||||
if(!pHori) {
|
||||
FIXME("Can't find HHEA table - not TT font?\n");
|
||||
goto end;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pPost = pFT_Get_Sfnt_Table(ft_face, ft_sfnt_post); /* we can live with this failing */
|
||||
|
@ -7078,10 +6929,9 @@ static BOOL get_outline_text_metrics(GdiFont *font)
|
|||
pHori->Ascender, pHori->Descender, pHori->Line_Gap,
|
||||
ft_face->bbox.yMax, ft_face->bbox.yMin);
|
||||
|
||||
font->potm = HeapAlloc(GetProcessHeap(), 0, needed);
|
||||
font->potm->otmSize = needed;
|
||||
font->otm.otmSize = needed;
|
||||
|
||||
#define TM font->potm->otmTextMetrics
|
||||
#define TM font->otm.otmTextMetrics
|
||||
|
||||
windescent = get_fixed_windescent(pOS2->usWinDescent);
|
||||
if(pOS2->usWinAscent + windescent == 0) {
|
||||
|
@ -7092,15 +6942,15 @@ static BOOL get_outline_text_metrics(GdiFont *font)
|
|||
descent = windescent;
|
||||
}
|
||||
|
||||
gdi_font->ntmCellHeight = ascent + descent;
|
||||
gdi_font->ntmAvgWidth = pOS2->xAvgCharWidth;
|
||||
font->ntmCellHeight = ascent + descent;
|
||||
font->ntmAvgWidth = pOS2->xAvgCharWidth;
|
||||
|
||||
#define SCALE_X(x) (pFT_MulFix(x, em_scale))
|
||||
#define SCALE_Y(y) (pFT_MulFix(y, em_scale))
|
||||
|
||||
if(gdi_font->yMax) {
|
||||
TM.tmAscent = gdi_font->yMax;
|
||||
TM.tmDescent = -gdi_font->yMin;
|
||||
if(font->yMax) {
|
||||
TM.tmAscent = font->yMax;
|
||||
TM.tmDescent = -font->yMin;
|
||||
TM.tmInternalLeading = (TM.tmAscent + TM.tmDescent) - ft_face->size->metrics.y_ppem;
|
||||
} else {
|
||||
TM.tmAscent = SCALE_Y(ascent);
|
||||
|
@ -7123,7 +6973,7 @@ static BOOL get_outline_text_metrics(GdiFont *font)
|
|||
}
|
||||
TM.tmMaxCharWidth = SCALE_X(ft_face->bbox.xMax - ft_face->bbox.xMin);
|
||||
TM.tmWeight = FW_REGULAR;
|
||||
if (gdi_font->fake_bold)
|
||||
if (font->fake_bold)
|
||||
TM.tmWeight = FW_BOLD;
|
||||
else
|
||||
{
|
||||
|
@ -7172,9 +7022,9 @@ static BOOL get_outline_text_metrics(GdiFont *font)
|
|||
TM.tmBreakChar = pOS2->usFirstCharIndex;
|
||||
TM.tmDefaultChar = TM.tmBreakChar - 1;
|
||||
}
|
||||
TM.tmItalic = gdi_font->fake_italic ? 255 : ((ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0);
|
||||
TM.tmUnderlined = gdi_font->lf.lfUnderline ? 255 : 0;
|
||||
TM.tmStruckOut = gdi_font->lf.lfStrikeOut ? 255 : 0;
|
||||
TM.tmItalic = font->fake_italic ? 255 : ((ft_face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0);
|
||||
TM.tmUnderlined = font->lf.lfUnderline ? 255 : 0;
|
||||
TM.tmStruckOut = font->lf.lfStrikeOut ? 255 : 0;
|
||||
|
||||
/* Yes TPMF_FIXED_PITCH is correct; braindead api */
|
||||
if(!FT_IS_FIXED_WIDTH(ft_face) &&
|
||||
|
@ -7242,112 +7092,61 @@ static BOOL get_outline_text_metrics(GdiFont *font)
|
|||
|
||||
if(FT_IS_SFNT(ft_face))
|
||||
{
|
||||
if (gdi_font->ntmFlags & NTM_PS_OPENTYPE)
|
||||
if (font->ntmFlags & NTM_PS_OPENTYPE)
|
||||
TM.tmPitchAndFamily |= TMPF_DEVICE;
|
||||
else
|
||||
TM.tmPitchAndFamily |= TMPF_TRUETYPE;
|
||||
}
|
||||
|
||||
TM.tmCharSet = gdi_font->charset;
|
||||
TM.tmCharSet = font->charset;
|
||||
|
||||
font->potm->otmFiller = 0;
|
||||
memcpy(&font->potm->otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
|
||||
font->potm->otmfsSelection = pOS2->fsSelection;
|
||||
if (gdi_font->fake_italic)
|
||||
font->potm->otmfsSelection |= 1;
|
||||
if (gdi_font->fake_bold)
|
||||
font->potm->otmfsSelection |= 1 << 5;
|
||||
font->otm.otmFiller = 0;
|
||||
memcpy(&font->otm.otmPanoseNumber, pOS2->panose, PANOSE_COUNT);
|
||||
font->otm.otmfsSelection = pOS2->fsSelection;
|
||||
if (font->fake_italic)
|
||||
font->otm.otmfsSelection |= 1;
|
||||
if (font->fake_bold)
|
||||
font->otm.otmfsSelection |= 1 << 5;
|
||||
/* Only return valid bits that define embedding and subsetting restrictions */
|
||||
font->potm->otmfsType = pOS2->fsType & 0x30e;
|
||||
font->potm->otmsCharSlopeRise = pHori->caret_Slope_Rise;
|
||||
font->potm->otmsCharSlopeRun = pHori->caret_Slope_Run;
|
||||
font->potm->otmItalicAngle = 0; /* POST table */
|
||||
font->potm->otmEMSquare = ft_face->units_per_EM;
|
||||
font->potm->otmAscent = SCALE_Y(pOS2->sTypoAscender);
|
||||
font->potm->otmDescent = SCALE_Y(pOS2->sTypoDescender);
|
||||
font->potm->otmLineGap = SCALE_Y(pOS2->sTypoLineGap);
|
||||
font->potm->otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight);
|
||||
font->potm->otmsXHeight = SCALE_Y(pOS2->sxHeight);
|
||||
font->potm->otmrcFontBox.left = SCALE_X(ft_face->bbox.xMin);
|
||||
font->potm->otmrcFontBox.right = SCALE_X(ft_face->bbox.xMax);
|
||||
font->potm->otmrcFontBox.top = SCALE_Y(ft_face->bbox.yMax);
|
||||
font->potm->otmrcFontBox.bottom = SCALE_Y(ft_face->bbox.yMin);
|
||||
font->potm->otmMacAscent = TM.tmAscent;
|
||||
font->potm->otmMacDescent = -TM.tmDescent;
|
||||
font->potm->otmMacLineGap = SCALE_Y(pHori->Line_Gap);
|
||||
font->potm->otmusMinimumPPEM = 0; /* TT Header */
|
||||
font->potm->otmptSubscriptSize.x = SCALE_X(pOS2->ySubscriptXSize);
|
||||
font->potm->otmptSubscriptSize.y = SCALE_Y(pOS2->ySubscriptYSize);
|
||||
font->potm->otmptSubscriptOffset.x = SCALE_X(pOS2->ySubscriptXOffset);
|
||||
font->potm->otmptSubscriptOffset.y = SCALE_Y(pOS2->ySubscriptYOffset);
|
||||
font->potm->otmptSuperscriptSize.x = SCALE_X(pOS2->ySuperscriptXSize);
|
||||
font->potm->otmptSuperscriptSize.y = SCALE_Y(pOS2->ySuperscriptYSize);
|
||||
font->potm->otmptSuperscriptOffset.x = SCALE_X(pOS2->ySuperscriptXOffset);
|
||||
font->potm->otmptSuperscriptOffset.y = SCALE_Y(pOS2->ySuperscriptYOffset);
|
||||
font->potm->otmsStrikeoutSize = SCALE_Y(pOS2->yStrikeoutSize);
|
||||
font->potm->otmsStrikeoutPosition = SCALE_Y(pOS2->yStrikeoutPosition);
|
||||
font->otm.otmfsType = pOS2->fsType & 0x30e;
|
||||
font->otm.otmsCharSlopeRise = pHori->caret_Slope_Rise;
|
||||
font->otm.otmsCharSlopeRun = pHori->caret_Slope_Run;
|
||||
font->otm.otmItalicAngle = 0; /* POST table */
|
||||
font->otm.otmEMSquare = ft_face->units_per_EM;
|
||||
font->otm.otmAscent = SCALE_Y(pOS2->sTypoAscender);
|
||||
font->otm.otmDescent = SCALE_Y(pOS2->sTypoDescender);
|
||||
font->otm.otmLineGap = SCALE_Y(pOS2->sTypoLineGap);
|
||||
font->otm.otmsCapEmHeight = SCALE_Y(pOS2->sCapHeight);
|
||||
font->otm.otmsXHeight = SCALE_Y(pOS2->sxHeight);
|
||||
font->otm.otmrcFontBox.left = SCALE_X(ft_face->bbox.xMin);
|
||||
font->otm.otmrcFontBox.right = SCALE_X(ft_face->bbox.xMax);
|
||||
font->otm.otmrcFontBox.top = SCALE_Y(ft_face->bbox.yMax);
|
||||
font->otm.otmrcFontBox.bottom = SCALE_Y(ft_face->bbox.yMin);
|
||||
font->otm.otmMacAscent = TM.tmAscent;
|
||||
font->otm.otmMacDescent = -TM.tmDescent;
|
||||
font->otm.otmMacLineGap = SCALE_Y(pHori->Line_Gap);
|
||||
font->otm.otmusMinimumPPEM = 0; /* TT Header */
|
||||
font->otm.otmptSubscriptSize.x = SCALE_X(pOS2->ySubscriptXSize);
|
||||
font->otm.otmptSubscriptSize.y = SCALE_Y(pOS2->ySubscriptYSize);
|
||||
font->otm.otmptSubscriptOffset.x = SCALE_X(pOS2->ySubscriptXOffset);
|
||||
font->otm.otmptSubscriptOffset.y = SCALE_Y(pOS2->ySubscriptYOffset);
|
||||
font->otm.otmptSuperscriptSize.x = SCALE_X(pOS2->ySuperscriptXSize);
|
||||
font->otm.otmptSuperscriptSize.y = SCALE_Y(pOS2->ySuperscriptYSize);
|
||||
font->otm.otmptSuperscriptOffset.x = SCALE_X(pOS2->ySuperscriptXOffset);
|
||||
font->otm.otmptSuperscriptOffset.y = SCALE_Y(pOS2->ySuperscriptYOffset);
|
||||
font->otm.otmsStrikeoutSize = SCALE_Y(pOS2->yStrikeoutSize);
|
||||
font->otm.otmsStrikeoutPosition = SCALE_Y(pOS2->yStrikeoutPosition);
|
||||
if(!pPost) {
|
||||
font->potm->otmsUnderscoreSize = 0;
|
||||
font->potm->otmsUnderscorePosition = 0;
|
||||
font->otm.otmsUnderscoreSize = 0;
|
||||
font->otm.otmsUnderscorePosition = 0;
|
||||
} else {
|
||||
font->potm->otmsUnderscoreSize = SCALE_Y(pPost->underlineThickness);
|
||||
font->potm->otmsUnderscorePosition = SCALE_Y(pPost->underlinePosition);
|
||||
font->otm.otmsUnderscoreSize = SCALE_Y(pPost->underlineThickness);
|
||||
font->otm.otmsUnderscorePosition = SCALE_Y(pPost->underlinePosition);
|
||||
}
|
||||
#undef SCALE_X
|
||||
#undef SCALE_Y
|
||||
#undef TM
|
||||
|
||||
/* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
|
||||
cp = (char*)font->potm + sizeof(*font->potm);
|
||||
font->potm->otmpFamilyName = (LPSTR)(cp - (char*)font->potm);
|
||||
strcpyW((WCHAR*)cp, family_nameW);
|
||||
cp += lenfam;
|
||||
font->potm->otmpStyleName = (LPSTR)(cp - (char*)font->potm);
|
||||
strcpyW((WCHAR*)cp, style_nameW);
|
||||
cp += lensty;
|
||||
font->potm->otmpFaceName = (LPSTR)(cp - (char*)font->potm);
|
||||
strcpyW((WCHAR*)cp, face_nameW);
|
||||
cp += lenface;
|
||||
font->potm->otmpFullName = (LPSTR)(cp - (char*)font->potm);
|
||||
strcpyW((WCHAR*)cp, full_nameW);
|
||||
ret = TRUE;
|
||||
|
||||
end:
|
||||
HeapFree(GetProcessHeap(), 0, style_nameW);
|
||||
HeapFree(GetProcessHeap(), 0, family_nameW);
|
||||
HeapFree(GetProcessHeap(), 0, face_nameW);
|
||||
HeapFree(GetProcessHeap(), 0, full_nameW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* freetype_GetTextMetrics
|
||||
*/
|
||||
static BOOL CDECL freetype_GetTextMetrics( struct gdi_font *font, TEXTMETRICW *metrics )
|
||||
{
|
||||
return get_text_metrics( get_font_ptr(font), metrics );
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* freetype_GetOutlineTextMetrics
|
||||
*/
|
||||
static UINT CDECL freetype_GetOutlineTextMetrics( struct gdi_font *gdi_font, UINT cbSize, OUTLINETEXTMETRICW *potm )
|
||||
{
|
||||
GdiFont *font = get_font_ptr(gdi_font);
|
||||
UINT ret = 0;
|
||||
|
||||
TRACE("font=%p\n", font);
|
||||
|
||||
if (font->potm || get_outline_text_metrics( font ))
|
||||
{
|
||||
if(potm && cbSize >= font->potm->otmSize)
|
||||
{
|
||||
memcpy(potm, font->potm, font->potm->otmSize);
|
||||
scale_outline_font_metrics(font, potm);
|
||||
}
|
||||
ret = font->potm->otmSize;
|
||||
}
|
||||
return ret;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL load_child_font(GdiFont *font, CHILD_FONT *child)
|
||||
|
@ -7394,7 +7193,8 @@ static BOOL load_child_font(GdiFont *font, CHILD_FONT *child)
|
|||
child_font->ntmFlags = child_face->ntmFlags;
|
||||
child_font->aa_flags = HIWORD( child_face->flags );
|
||||
child_font->scale_y = gdi_font->scale_y;
|
||||
set_gdi_font_name( child_font, child_face->family->family_name );
|
||||
set_gdi_font_names( child_font, child_face->family->family_name,
|
||||
child_face->style_name, child_face->full_name );
|
||||
child->font->base_font = font;
|
||||
TRACE("created child font %p for base %p\n", child->font, font);
|
||||
return TRUE;
|
||||
|
@ -7804,8 +7604,6 @@ static const struct font_backend_funcs font_funcs =
|
|||
freetype_GetCharWidthInfo,
|
||||
freetype_GetFontUnicodeRanges,
|
||||
freetype_GetKerningPairs,
|
||||
freetype_GetOutlineTextMetrics,
|
||||
freetype_GetTextMetrics,
|
||||
freetype_SelectFont,
|
||||
freetype_AddFontResourceEx,
|
||||
freetype_RemoveFontResourceEx,
|
||||
|
@ -7816,6 +7614,8 @@ static const struct font_backend_funcs font_funcs =
|
|||
freetype_get_glyph_index,
|
||||
freetype_get_default_glyph,
|
||||
freetype_get_glyph_outline,
|
||||
freetype_set_outline_text_metrics,
|
||||
freetype_set_bitmap_text_metrics,
|
||||
freetype_destroy_font
|
||||
};
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@ struct gdi_font
|
|||
DWORD refcount;
|
||||
DWORD gm_size;
|
||||
struct glyph_metrics **gm;
|
||||
OUTLINETEXTMETRICW otm;
|
||||
/* the following members can be accessed without locking, they are never modified after creation */
|
||||
void *private; /* font backend private data */
|
||||
DWORD handle;
|
||||
|
@ -337,7 +338,6 @@ struct gdi_font
|
|||
BOOL fake_italic : 1;
|
||||
BOOL fake_bold : 1;
|
||||
BOOL scalable : 1;
|
||||
WCHAR *name;
|
||||
void *data_ptr;
|
||||
SIZE_T data_size;
|
||||
FILETIME writetime;
|
||||
|
@ -360,8 +360,6 @@ struct font_backend_funcs
|
|||
BOOL (CDECL *pGetCharWidthInfo)( struct gdi_font *font, struct char_width_info *info );
|
||||
DWORD (CDECL *pGetFontUnicodeRanges)( struct gdi_font *font, GLYPHSET *glyphset );
|
||||
DWORD (CDECL *pGetKerningPairs)( struct gdi_font *font, DWORD count, KERNINGPAIR *pairs );
|
||||
UINT (CDECL *pGetOutlineTextMetrics)( struct gdi_font *font, UINT size, OUTLINETEXTMETRICW *metrics );
|
||||
BOOL (CDECL *pGetTextMetrics)( struct gdi_font *font, TEXTMETRICW *metrics );
|
||||
struct gdi_font * (CDECL *pSelectFont)( DC *dc, HFONT hfont, UINT *aa_flags, UINT default_aa_flags );
|
||||
|
||||
INT (CDECL *pAddFontResourceEx)( LPCWSTR file, DWORD flags, PVOID pdv );
|
||||
|
@ -377,6 +375,8 @@ struct font_backend_funcs
|
|||
UINT (CDECL *get_default_glyph)( struct gdi_font *gdi_font );
|
||||
DWORD (CDECL *get_glyph_outline)( struct gdi_font *font, UINT glyph, UINT format,
|
||||
GLYPHMETRICS *gm, ABC *abc, DWORD buflen, void *buf, const MAT2 *mat );
|
||||
BOOL (CDECL *set_outline_text_metrics)( struct gdi_font *font );
|
||||
BOOL (CDECL *set_bitmap_text_metrics)( struct gdi_font *font );
|
||||
void (CDECL *destroy_font)( struct gdi_font *font );
|
||||
};
|
||||
|
||||
|
@ -385,7 +385,9 @@ extern void free_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
|||
extern void cache_gdi_font( struct gdi_font *font ) DECLSPEC_HIDDEN;
|
||||
extern struct gdi_font *find_cached_gdi_font( const LOGFONTW *lf, const FMAT2 *matrix,
|
||||
BOOL can_use_bitmap ) DECLSPEC_HIDDEN;
|
||||
extern void set_gdi_font_name( struct gdi_font *font, const WCHAR *name ) DECLSPEC_HIDDEN;
|
||||
static inline const WCHAR *get_gdi_font_name( struct gdi_font *font ) { return (WCHAR *)font->otm.otmpFamilyName; }
|
||||
extern void set_gdi_font_names( struct gdi_font *font, const WCHAR *family_name, const WCHAR *style_name,
|
||||
const WCHAR *full_name ) DECLSPEC_HIDDEN;
|
||||
extern BOOL get_gdi_font_glyph_metrics( struct gdi_font *font, UINT index,
|
||||
GLYPHMETRICS *gm, ABC *abc ) DECLSPEC_HIDDEN;
|
||||
extern void set_gdi_font_glyph_metrics( struct gdi_font *font, UINT index,
|
||||
|
|
Loading…
Reference in New Issue