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>
This commit is contained in:
parent
7763efa347
commit
a554079860
|
@ -190,7 +190,7 @@ GpStatus WINGDIPAPI GdipCreateFont(GDIPCONST GpFontFamily *fontFamily,
|
||||||
(*font)->unit = unit;
|
(*font)->unit = unit;
|
||||||
(*font)->emSize = emSize;
|
(*font)->emSize = emSize;
|
||||||
(*font)->otm = otm;
|
(*font)->otm = otm;
|
||||||
(*font)->family = (GpFontFamily *)fontFamily;
|
GdipCloneFontFamily((GpFontFamily*)fontFamily, &(*font)->family);
|
||||||
|
|
||||||
TRACE("<-- %p\n", *font);
|
TRACE("<-- %p\n", *font);
|
||||||
|
|
||||||
|
@ -323,8 +323,7 @@ GpStatus WINGDIPAPI GdipGetFamily(GpFont *font, GpFontFamily **family)
|
||||||
if (!(font && family))
|
if (!(font && family))
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
*family = font->family;
|
return GdipCloneFontFamily(font->family, family);
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static REAL get_font_size(const GpFont *font)
|
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))
|
if (!wcsicmp(lf.lfFaceName, collection->FontFamilies[i]->FamilyName))
|
||||||
{
|
{
|
||||||
*family = collection->FontFamilies[i];
|
status = GdipCloneFontFamily(collection->FontFamilies[i], family);
|
||||||
TRACE("<-- %p\n", *family);
|
TRACE("<-- %p\n", *family);
|
||||||
status = Ok;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -778,6 +776,10 @@ GpStatus WINGDIPAPI GdipCloneFontFamily(GpFontFamily *family, GpFontFamily **clo
|
||||||
TRACE("%p (%s), %p\n", family, debugstr_w(family->FamilyName), clone);
|
TRACE("%p (%s), %p\n", family, debugstr_w(family->FamilyName), clone);
|
||||||
|
|
||||||
*clone = family;
|
*clone = family;
|
||||||
|
|
||||||
|
if (!family->installed)
|
||||||
|
InterlockedIncrement(&family->ref);
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +837,11 @@ GpStatus WINGDIPAPI GdipDeleteFontFamily(GpFontFamily *FontFamily)
|
||||||
if (!FontFamily)
|
if (!FontFamily)
|
||||||
return InvalidParameter;
|
return InvalidParameter;
|
||||||
|
|
||||||
|
if (!FontFamily->installed && !InterlockedDecrement(&FontFamily->ref))
|
||||||
|
{
|
||||||
|
heap_free(FontFamily);
|
||||||
|
}
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,7 +1086,7 @@ GpStatus WINGDIPAPI GdipDeletePrivateFontCollection(GpFontCollection **fontColle
|
||||||
if (!fontCollection)
|
if (!fontCollection)
|
||||||
return InvalidParameter;
|
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)->FontFamilies);
|
||||||
heap_free(*fontCollection);
|
heap_free(*fontCollection);
|
||||||
|
|
||||||
|
@ -1541,6 +1548,7 @@ GpStatus WINGDIPAPI GdipGetFontCollectionFamilyList(
|
||||||
|
|
||||||
for (i = 0; i < numSought && i < fontCollection->count; i++)
|
for (i = 0; i < numSought && i < fontCollection->count; i++)
|
||||||
{
|
{
|
||||||
|
/* caller is responsible for cloning these if it keeps references */
|
||||||
gpfamilies[i] = fontCollection->FontFamilies[i];
|
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->descent = fm.descent;
|
||||||
family->line_spacing = fm.line_spacing;
|
family->line_spacing = fm.line_spacing;
|
||||||
family->dpi = fm.dpi;
|
family->dpi = fm.dpi;
|
||||||
|
family->installed = param->is_system;
|
||||||
|
family->ref = 1;
|
||||||
|
|
||||||
lstrcpyW(family->FamilyName, lfw->lfFaceName);
|
lstrcpyW(family->FamilyName, lfw->lfFaceName);
|
||||||
|
|
||||||
|
|
|
@ -543,6 +543,8 @@ struct GpFontFamily{
|
||||||
WCHAR FamilyName[LF_FACESIZE];
|
WCHAR FamilyName[LF_FACESIZE];
|
||||||
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
|
UINT16 em_height, ascent, descent, line_spacing; /* in font units */
|
||||||
int dpi;
|
int dpi;
|
||||||
|
BOOL installed;
|
||||||
|
LONG ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* internal use */
|
/* internal use */
|
||||||
|
|
|
@ -72,7 +72,7 @@ static void test_long_name(void)
|
||||||
GpStatus stat;
|
GpStatus stat;
|
||||||
GpFontCollection *fonts;
|
GpFontCollection *fonts;
|
||||||
INT num_families;
|
INT num_families;
|
||||||
GpFontFamily *family;
|
GpFontFamily *family, *cloned_family;
|
||||||
WCHAR family_name[LF_FACESIZE];
|
WCHAR family_name[LF_FACESIZE];
|
||||||
GpFont *font;
|
GpFont *font;
|
||||||
|
|
||||||
|
@ -98,6 +98,10 @@ static void test_long_name(void)
|
||||||
stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font);
|
stat = GdipCreateFont(family, 256.0, FontStyleRegular, UnitPixel, &font);
|
||||||
ok(stat == Ok, "GdipCreateFont failed: %d\n", stat);
|
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 */
|
/* Cleanup */
|
||||||
|
|
||||||
stat = GdipDeleteFont(font);
|
stat = GdipDeleteFont(font);
|
||||||
|
@ -106,6 +110,13 @@ static void test_long_name(void)
|
||||||
stat = GdipDeletePrivateFontCollection(&fonts);
|
stat = GdipDeletePrivateFontCollection(&fonts);
|
||||||
ok(stat == Ok, "GdipDeletePrivateFontCollection failed: %d\n", stat);
|
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);
|
DELETE_FONTFILE(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue