Skip to content

Resizetizer: Decouple font and asset processing from platform-specific gates #34221

@Redth

Description

@Redth

Description

The Resizetizer's ProcessMauiFonts and ProcessMauiAssets targets perform fundamentally platform-agnostic work (copying font files, resolving asset paths) but are gated behind _ResizetizerIsCompatibleApp, which only allows five hard-coded platforms. Custom backends must re-implement trivial file copy logic because the existing targets refuse to run for them.

Part of #34099


Problem: Font Processing Is Gated

ProcessMauiFonts copies font files to an intermediate directory, then adds them to platform-specific item groups. The copy step is universal; only the item group injection is platform-specific.

However, the target only runs when _ResizetizerIsCompatibleApp is true (via the ProcessMauiFontsDependsOnTargets chain which includes ResizetizeCollectItems, which has the compatibility condition).

The internal pipeline is:

ResizetizeCollectItems (requires _ResizetizerIsCompatibleApp)
    → ProcessMauiAssets
    → ProcessMauiSplashScreens
    → ProcessMauiFonts

Custom backends never enter this chain, so ProcessMauiFonts never runs — even though it's just copying .ttf/.otf files.

Problem: Asset Processing Has the Same Gate + No Fallback Metadata

ProcessMauiAssets uses the GetMauiAssetPath task to resolve logical paths, with the metadata destination determined per platform:

<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsAndroidApp)' == 'True'">Link</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsiOSApp)' == 'True'">Link</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsWindowsAppSdk)' == 'True'">TargetPath</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsTizenApp)' == 'True'">TizenTpkFileName</_MauiAssetItemMetadata>

If none of those conditions match, _MauiAssetItemMetadata is empty and the GetMauiAssetPath task fails or produces no useful output.


Proposed Solution

Change 1: Expose Processed Fonts as a Public Item Group

After the font copy step (which is platform-agnostic), expose the results so custom backends can consume them:

<Target Name="ProcessMauiFonts"
        Condition="'$(EnableMauiFontProcessing)' == 'true'"
        ...>

    <!-- Existing: Copy fonts to intermediate dir -->
    <Copy SourceFiles="@(MauiFont)" DestinationFolder="$(_MauiIntermediateFonts)" SkipUnchangedFiles="true" />

    <ItemGroup>
        <_MauiFontCopied Include="$(_MauiIntermediateFonts)*" />
    </ItemGroup>

    <!-- Existing platform-specific injection (unchanged) -->
    <ItemGroup Condition="'$(_ResizetizerIsiOSApp)' == 'True' And '@(_MauiFontCopied)' != ''">
        ...
    </ItemGroup>
    <!-- ... other platforms ... -->

    <!-- NEW: Make processed fonts available to custom backends -->
    <ItemGroup>
        <MauiProcessedFont Include="@(_MauiFontCopied)" />
    </ItemGroup>

    ...
</Target>

Custom backends consume via AfterTargets:

<Target Name="_MacOSBundleFonts" AfterTargets="ProcessMauiFonts">
    <ItemGroup>
        <BundleResource Include="@(MauiProcessedFont)">
            <LogicalName>%(Filename)%(Extension)</LogicalName>
        </BundleResource>
    </ItemGroup>
</Target>

Change 2: Add Default Asset Metadata Fallback

Add a single line to provide a sensible default:

<!-- EXISTING per-platform settings -->
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsAndroidApp)' == 'True'">Link</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsiOSApp)' == 'True'">Link</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsWindowsAppSdk)' == 'True'">TargetPath</_MauiAssetItemMetadata>
<_MauiAssetItemMetadata Condition="'$(_ResizetizerIsTizenApp)' == 'True'">TizenTpkFileName</_MauiAssetItemMetadata>

<!-- NEW: Default for unknown/custom platforms -->
<_MauiAssetItemMetadata Condition="'$(_MauiAssetItemMetadata)' == ''">Link</_MauiAssetItemMetadata>

Similarly, expose processed assets:

<!-- After GetMauiAssetPath runs -->
<ItemGroup>
    <MauiProcessedAsset Include="@(_MauiAssetItemWithMetadata)" />
</ItemGroup>

Change 3: Allow ProcessMauiFonts and ProcessMauiAssets to Run Independently

The simplest fix is to not require _ResizetizerIsCompatibleApp for the ResizetizeCollectItems target when it's being used only for font/asset collection. Alternatively, add standalone entry points:

<!-- Font processing should work for any platform that has MauiFont items -->
<PropertyGroup Condition="'@(MauiFont)' != '' And '$(EnableMauiFontProcessing)' == 'true'">
    <ProcessMauiFontsDependsOnTargets>
        $(ProcessMauiFontsDependsOnTargets);
        ResizetizeCollectItems;
    </ProcessMauiFontsDependsOnTargets>
</PropertyGroup>

Or simply make ResizetizeCollectItems always run (its job is just gathering items — the conditional should be on the targets that process them, not on the target that collects them).


Impact

  • Zero breaking changes — existing platforms are unaffected
  • ~15 lines of code total
  • Fonts and assets "just work" for any backend that references the Resizetizer NuGet
  • Font processing is the simplest and most universal resource type — there's no reason to gate it

Files Changed

  1. src/SingleProject/Resizetizer/src/nuget/buildTransitive/Microsoft.Maui.Resizetizer.After.targets
    • Add MauiProcessedFont and MauiProcessedAsset public item groups
    • Add default _MauiAssetItemMetadata fallback
    • Relax ResizetizeCollectItems condition or add standalone entry points

Metadata

Metadata

Assignees

No one assigned

    Labels

    s/triagedIssue has been reviewed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions