Allow arbitrary strings for thmutil Font ids.
Sean Hall committed
Jun 4, 2021 at 13:36 UTC
34639850c2c07a35c1e502e174866cd8630eb8ec
2 files changed
+39
-16
src/libs/dutil/WixToolset.DUtil/inc/thmutil.h
+3
@@ -295,6 +295,8 @@ struct THEME_FONT_INSTANCE
295
296
struct THEME_FONT
297
{
298
+ LPWSTR sczId;
299
+ DWORD dwIndex;
300
LONG lfHeight;
301
LONG lfWeight;
302
BYTE lfUnderline;
@@ -353,6 +355,7 @@ struct THEME
355
THEME_CONTROL* rgControls;
356
357
// internal state variables -- do not use outside ThmUtil.cpp
358
+ STRINGDICT_HANDLE sdhFontDictionary;
359
HWND hwndParent; // parent for loaded controls
360
HWND hwndHover; // current hwnd hovered over
361
DWORD dwCurrentPageId;
src/libs/dutil/WixToolset.DUtil/thmutil.cpp
+36
-16
@@ -134,6 +134,7 @@ static HRESULT GetAttributeCoordinateOrDimension(
134
__inout int* pnValue
135
);
136
static HRESULT GetAttributeFontId(
137
+ __in THEME* pTheme,
138
__in IXMLDOMNode* pixn,
139
__in LPCWSTR wzAttribute,
140
__inout DWORD* pdwValue
@@ -710,6 +711,7 @@ DAPI_(void) ThemeFree(
711
ReleaseMem(pTheme->rgFonts);
712
713
ReleaseStr(pTheme->sczCaption);
714
+ ReleaseDict(pTheme->sdhFontDictionary);
715
ReleaseMem(pTheme);
716
}
717
}
@@ -2248,30 +2250,37 @@ LExit:
2250
}
2251
2252
static HRESULT GetAttributeFontId(
2253
+ __in THEME* pTheme,
2254
__in IXMLDOMNode* pixn,
2255
__in LPCWSTR wzAttribute,
2256
__inout DWORD* pdwValue
2257
)
2258
{
2259
HRESULT hr = S_OK;
2257
- DWORD dwValue = 0;
2260
+ BSTR bstrId = NULL;
2261
+ THEME_FONT* pFont = NULL;
2262
BOOL fXmlFound = FALSE;
2263
2260
- hr = XmlGetAttributeUInt32(pixn, wzAttribute, &dwValue);
2264
+ hr = XmlGetAttribute(pixn, wzAttribute, &bstrId);
2265
ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed to get font id attribute.");
2266
2267
if (!fXmlFound)
2268
{
2269
ExitFunction1(hr = E_NOTFOUND);
2270
}
2267
- else if (THEME_INVALID_ID == dwValue)
2271
+
2272
+ hr = DictGetValue(pTheme->sdhFontDictionary, bstrId, reinterpret_cast<void**>(&pFont));
2273
+ if (E_NOTFOUND == hr)
2274
{
2269
- ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid font id value: %u", dwValue);
2275
+ ThmExitWithRootFailure(hr, E_INVALIDDATA, "Unknown font id: %ls", bstrId);
2276
}
2277
+ ThmExitOnFailure(hr, "Failed to find font with id: %ls", bstrId);
2278
2272
- *pdwValue = dwValue;
2279
+ *pdwValue = pFont->dwIndex;
2280
2281
LExit:
2282
+ ReleaseBSTR(bstrId);
2283
+
2284
return hr;
2285
}
2286
@@ -2441,7 +2450,7 @@ static HRESULT ParseWindow(
2450
pTheme->nMinimumHeight = pTheme->nDefaultDpiMinimumHeight = nValue;
2451
}
2452
2444
- hr = GetAttributeFontId(pixn, L"FontId", &pTheme->dwFontId);
2453
+ hr = GetAttributeFontId(pTheme, pixn, L"FontId", &pTheme->dwFontId);
2454
ThmExitOnRequiredXmlQueryFailure(hr, "Failed to get window FontId attribute.");
2455
2456
// Get the optional window icon from a resource.
@@ -2546,6 +2555,7 @@ static HRESULT ParseFonts(
2555
HRESULT hr = S_OK;
2556
IXMLDOMNodeList* pixnl = NULL;
2557
IXMLDOMNode* pixn = NULL;
2558
+ LPWSTR sczFontId = NULL;
2559
BSTR bstrName = NULL;
2560
DWORD dwId = 0;
2561
BOOL fXmlFound = FALSE;
@@ -2568,21 +2578,26 @@ static HRESULT ParseFonts(
2578
pTheme->rgFonts = static_cast<THEME_FONT*>(MemAlloc(sizeof(THEME_FONT) * pTheme->cFonts, TRUE));
2579
ThmExitOnNull(pTheme->rgFonts, hr, E_OUTOFMEMORY, "Failed to allocate theme fonts.");
2580
2581
+ hr = DictCreateWithEmbeddedKey(&pTheme->sdhFontDictionary, pTheme->cFonts, reinterpret_cast<void**>(&pTheme->rgFonts), offsetof(THEME_FONT, sczId), DICT_FLAG_NONE);
2582
+ ThmExitOnFailure(hr, "Failed to create font dictionary.");
2583
+
2584
while (S_OK == (hr = XmlNextElement(pixnl, &pixn, NULL)))
2585
{
2573
- hr = GetAttributeFontId(pixn, L"Id", &dwId);
2586
+ hr = XmlGetAttributeEx(pixn, L"Id", &sczFontId);
2587
ThmExitOnRequiredXmlQueryFailure(hr, "Failed to find font id.");
2588
2576
- if (pTheme->cFonts <= dwId)
2589
+ hr = DictKeyExists(pTheme->sdhFontDictionary, sczFontId);
2590
+ if (E_NOTFOUND != hr)
2591
{
2578
- ThmExitWithRootFailure(hr, E_INVALIDDATA, "Invalid theme font id: %u.", dwId);
2592
+ ThmExitOnFailure(hr, "Failed to check for duplicate font id.");
2593
+ ThmExitWithRootFailure(hr, E_INVALIDDATA, "Theme font id duplicated: %ls", sczFontId);
2594
}
2595
2596
THEME_FONT* pFont = pTheme->rgFonts + dwId;
2582
- if (pFont->cFontInstances)
2583
- {
2584
- ThmExitWithRootFailure(hr, E_INVALIDDATA, "Theme font id duplicated.");
2585
- }
2597
+ pFont->sczId = sczFontId;
2598
+ sczFontId = NULL;
2599
+ pFont->dwIndex = dwId;
2600
+ ++dwId;
2601
2602
pFont->lfQuality = CLEARTYPE_QUALITY;
2603
@@ -2631,6 +2646,9 @@ static HRESULT ParseFonts(
2646
ThmExitOnNull(pFont->hBackground, hr, E_OUTOFMEMORY, "Failed to create text background brush.");
2647
}
2648
2649
+ hr = DictAddValue(pTheme->sdhFontDictionary, pFont);
2650
+ ThmExitOnFailure(hr, "Failed to add font to dictionary.");
2651
+
2652
ReleaseNullBSTR(bstrName);
2653
ReleaseNullObject(pixn);
2654
}
@@ -2643,6 +2661,7 @@ static HRESULT ParseFonts(
2661
2662
LExit:
2663
ReleaseBSTR(bstrName);
2664
+ ReleaseStr(sczFontId);
2665
ReleaseObject(pixn);
2666
ReleaseObject(pixnl);
2667
@@ -3185,7 +3204,7 @@ static HRESULT ParseControl(
3204
}
3205
3206
3188
- hr = GetAttributeFontId(pixn, L"FontId", &pControl->dwFontId);
3207
+ hr = GetAttributeFontId(pTheme, pixn, L"FontId", &pControl->dwFontId);
3208
ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control FontId attribute.");
3209
3210
// Parse the optional window style.
@@ -3291,10 +3310,10 @@ static HRESULT ParseControl(
3310
}
3311
else if (THEME_CONTROL_TYPE_HYPERLINK == pControl->type || THEME_CONTROL_TYPE_BUTTON == pControl->type)
3312
{
3294
- hr = GetAttributeFontId(pixn, L"HoverFontId", &pControl->dwFontHoverId);
3313
+ hr = GetAttributeFontId(pTheme, pixn, L"HoverFontId", &pControl->dwFontHoverId);
3314
ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control HoverFontId attribute.");
3315
3297
- hr = GetAttributeFontId(pixn, L"SelectedFontId", &pControl->dwFontSelectedId);
3316
+ hr = GetAttributeFontId(pTheme, pixn, L"SelectedFontId", &pControl->dwFontSelectedId);
3317
ThmExitOnOptionalXmlQueryFailure(hr, fXmlFound, "Failed when querying control SelectedFontId attribute.");
3318
}
3319
else if (THEME_CONTROL_TYPE_LABEL == pControl->type)
@@ -4697,6 +4716,7 @@ static void FreeFont(
4716
4717
ReleaseMem(pFont->rgFontInstances);
4718
ReleaseStr(pFont->sczFaceName);
4719
+ ReleaseStr(pFont->sczId);
4720
}
4721
}
4722