gdiplus: Implement reference counting for private font families.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50896
Signed-off-by: Esme Povirk <esme@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
(cherry picked from commit a554079860
)
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
This commit is contained in:
parent
bf92d6bedf
commit
a0b7fb69e7
|
@ -190,7 +190,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
|||
(*font)->unit = unit;
|
||||
(*font)->emSize = emSize;
|
||||
(*font)->otm = otm;
|
||||
(*font)->family = (GpFontFamily *)fontFamily;
|
||||
GdipCloneFontFamily((GpFontFamily*)fontFamily, &(*font)->family);
|
||||
|
||||
TRACE("<-- %p\n", *font);
|
||||
|
||||
|
@ -323,8 +323,7 @@ GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
|
|||
if (!(font && family))
|
||||
return InvalidParameter;
|
||||
|
||||
*family = font->family;
|
||||
return Ok;
|
||||
return GdipCloneFontFamily(font->family, family);
|
||||
}
|
||||
|
||||
static REAL get_font_size(const GpFont *font)
|
||||
|
@ -746,9 +745,8 @@ GpStatus WINGDIPAPI GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
|
|||
{
|
||||
if (!wcsicmp(lf.lfFaceName, collection->FontFamilies[i]->FamilyName))
|
||||
{
|
||||
*family = collection->FontFamilies[i];
|
||||
status = GdipCloneFontFamily(collection->FontFamilies[i], family);
|
||||
TRACE("<-- %p\n", *family);
|
||||
status = Ok;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -778,6 +776,10 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily *family, GpFontFamily **clo
|
|||
TRACE("%p (%s), %p\n", family, debugstr_w(family->FamilyName), clone);
|
||||
|
||||
*clone = family;
|
||||
|
||||
if (!family->installed)
|
||||
InterlockedIncrement(&family->ref);
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -835,6 +837,11 @@ GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
|
|||
if (!FontFamily)
|
||||
return InvalidParameter;
|
||||
|
||||
if (!FontFamily->installed && !InterlockedDecrement(&FontFamily->ref))
|
||||
{
|
||||
heap_free(FontFamily);
|
||||
}
|
||||
|
||||
return Ok;
|
||||
}
|
||||
|
||||
|
@ -1079,7 +1086,7 @@ GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontColle
|
|||
if (!fontCollection)
|
||||
return InvalidParameter;
|
||||
|
||||
for (i = 0; i < (*fontCollection)->count; i++) heap_free((*fontCollection)->FontFamilies[i]);
|
||||
for (i = 0; i < (*fontCollection)->count; i++) GdipDeleteFontFamily((*fontCollection)->FontFamilies[i]);
|
||||
heap_free((*fontCollection)->FontFamilies);
|
||||
heap_free(*fontCollection);
|
||||
|
||||
|
@ -1541,6 +1548,7 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
|
|||
|
||||
for (i = 0; i < numSought && i < fontCollection->count; i++)
|
||||
{
|
||||
/* caller is responsible for cloning these if it keeps references */
|
||||
gpfamilies[i] = fontCollection->FontFamilies[i];
|
||||
}
|
||||
|
||||
|
@ -1641,6 +1649,8 @@ static INT CALLBACK add_font_proc(const LOGFONTW *lfw, const TEXTMETRICW *ntm,
|
|||
family->descent = fm.descent;
|
||||
family->line_spacing = fm.line_spacing;
|
||||
family->dpi = fm.dpi;
|
||||
family->installed = param->is_system;
|
||||
family->ref = 1;
|
||||
|
||||
lstrcpyW(family->FamilyName, lfw->lfFaceName);
|
||||
|
||||
|
|
|
@ -528,6 +528,8 @@ struct GpFontFamily{
|
|||
WCHAR FamilyName[LF_FACESIZE];
|
||||
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
|
||||
int dpi;
|
||||
BOOL installed;
|
||||
LONG ref;
|
||||
};
|
||||
|
||||
/* internal use */
|
||||
|
|
|
@ -72,7 +72,7 @@ static void test_long_name(void)
|
|||
GpStatus stat;
|
||||
GpFontCollection *fonts;
|
||||
INT num_families;
|
||||
GpFontFamily *family;
|
||||
GpFontFamily *family, *cloned_family;
|
||||
WCHAR family_name[LF_FACESIZE];
|
||||
GpFont *font;
|
||||
|
||||
|
@ -98,6 +98,10 @@ static void test_long_name(void)
|
|||
stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font);
|
||||
ok(stat == Ok, "GdipCreateFont failed: %d\n", stat);
|
||||
|
||||
stat = GdipCloneFontFamily(family, &cloned_family);
|
||||
ok(stat == Ok, "GdipCloneFontFamily failed: %d\n", stat);
|
||||
ok(family == cloned_family, "GdipCloneFontFamily returned new object\n");
|
||||
|
||||
/* Cleanup */
|
||||
|
||||
stat = GdipDeleteFont(font);
|
||||
|
@ -106,6 +110,13 @@ static void test_long_name(void)
|
|||
stat = GdipDeletePrivateFontCollection(&fonts);
|
||||
ok(stat == Ok, "GdipDeletePrivateFontCollection failed: %d\n", stat);
|
||||
|
||||
/* Cloned family survives after collection is deleted */
|
||||
stat = GdipGetFamilyName(cloned_family, family_name, LANG_NEUTRAL);
|
||||
ok(stat == Ok, "GdipGetFamilyName failed: %d\n", stat);
|
||||
|
||||
stat = GdipDeleteFontFamily(cloned_family);
|
||||
ok(stat == Ok, "GdipDeleteFontFamily failed: %d\n", stat);
|
||||
|
||||
DELETE_FONTFILE(path);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue