@joebigelow / wix-1 / commits / 34639850

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