Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,33 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface

return success;
}

/// Checks whether the font face contains a COLR table by probing via
/// IDWriteFontFace::TryGetFontTable. The table data is immediately released
/// since we only need to know whether the table exists, not its contents.
/// TranslateColorGlyphRun does its own deep parsing of COLR/CPAL.
__declspec(noinline) bool FontFace::HasColorGlyphs()
{
const void* tableData;
void* tableContext;
UINT32 tableSize = 0;
BOOL exists = FALSE;

HRESULT hr = _fontFace->Value->TryGetFontTable(
DWRITE_MAKE_OPENTYPE_TAG('C','O','L','R'),
&tableData,
&tableSize,
&tableContext,
&exists
);

if (SUCCEEDED(hr) && exists)
{
_fontFace->Value->ReleaseFontTable(tableContext);
}

System::GC::KeepAlive(_fontFace);
return (!!exists);
}

}}}}//MS::Internal::Text::TextInterface
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ namespace MS { namespace Internal { namespace Text { namespace TextInterface
/// <returns>True if os2 table exists and the FontEmbeddingRights was read successfully.</returns>
bool ReadFontEmbeddingRights([System::Runtime::InteropServices::Out] unsigned short% fsType);

/// <summary>
/// Returns true if the font face contains a COLR (Color) OpenType table,
/// indicating it has color glyph layer definitions. Only checks for table
/// presence, not validity -- a corrupt COLR table would return true here
/// but fail during TranslateColorGlyphRun.
/// </summary>
bool HasColorGlyphs();

/// <summary>
/// dtor.
/// </summary>
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;

namespace MS.Internal.Interop.DWrite
{
[StructLayout(LayoutKind.Sequential)]
internal struct DWRITE_GLYPH_OFFSET
{
public float advanceOffset;
public float ascenderOffset;
}

[StructLayout(LayoutKind.Sequential)]
internal unsafe struct DWRITE_GLYPH_RUN
{
public void* fontFace; // IDWriteFontFace*
public float fontEmSize;
public uint glyphCount;
public ushort* glyphIndices;
public float* glyphAdvances;
public DWRITE_GLYPH_OFFSET* glyphOffsets;
public int isSideways; // BOOL (4 bytes)
public uint bidiLevel;
}

[StructLayout(LayoutKind.Sequential)]
internal struct DWRITE_COLOR_F
{
public float r;
public float g;
public float b;
public float a;
}

[StructLayout(LayoutKind.Sequential)]
internal unsafe struct DWRITE_COLOR_GLYPH_RUN
{
public DWRITE_GLYPH_RUN glyphRun;
public void* glyphRunDescription; // DWRITE_GLYPH_RUN_DESCRIPTION* (nullable)
public float baselineOriginX;
public float baselineOriginY;
public DWRITE_COLOR_F runColor;
public ushort paletteIndex;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ο»Ώ// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;

namespace MS.Internal.Interop.DWrite
{
/// <summary>
/// Managed interop for IDWriteColorGlyphRunEnumerator COM interface.
/// Vtable layout: IUnknown (0-2), MoveNext (3), GetCurrentRun (4).
/// </summary>
internal unsafe struct IDWriteColorGlyphRunEnumerator
{
public void** lpVtbl;

public uint Release()
{
return ((delegate* unmanaged<IDWriteColorGlyphRunEnumerator*, uint>)(lpVtbl[2]))((IDWriteColorGlyphRunEnumerator*)Unsafe.AsPointer(ref this));
Comment thread
etvorun marked this conversation as resolved.
}

public int MoveNext(int* hasRun)
{
return ((delegate* unmanaged<IDWriteColorGlyphRunEnumerator*, int*, int>)(lpVtbl[3]))((IDWriteColorGlyphRunEnumerator*)Unsafe.AsPointer(ref this), hasRun);
}

public int GetCurrentRun(DWRITE_COLOR_GLYPH_RUN** colorGlyphRun)
{
return ((delegate* unmanaged<IDWriteColorGlyphRunEnumerator*, DWRITE_COLOR_GLYPH_RUN**, int>)(lpVtbl[4]))((IDWriteColorGlyphRunEnumerator*)Unsafe.AsPointer(ref this), colorGlyphRun);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;

namespace MS.Internal.Interop.DWrite
{
internal unsafe struct IDWriteFactory2 : IUnknown
{
public void** lpVtbl;

public int QueryInterface(Guid* riid, void** ppvObject)
{
return ((delegate* unmanaged<IDWriteFactory2*, Guid*, void**, int>)(lpVtbl[0]))((IDWriteFactory2*)Unsafe.AsPointer(ref this), riid, ppvObject);
}

public uint AddRef()
{
return ((delegate* unmanaged<IDWriteFactory2*, uint>)(lpVtbl[1]))((IDWriteFactory2*)Unsafe.AsPointer(ref this));
}

public uint Release()
{
return ((delegate* unmanaged<IDWriteFactory2*, uint>)(lpVtbl[2]))((IDWriteFactory2*)Unsafe.AsPointer(ref this));
}

public int TranslateColorGlyphRun(
float baselineOriginX,
float baselineOriginY,
DWRITE_GLYPH_RUN* glyphRun,
void* glyphRunDescription,
int measuringMode,
void* worldAndDpiTransform,
uint colorPaletteIndex,
IDWriteColorGlyphRunEnumerator** colorLayers)
{
return ((delegate* unmanaged<IDWriteFactory2*, float, float, DWRITE_GLYPH_RUN*, void*, int, void*, uint, IDWriteColorGlyphRunEnumerator**, int>)(lpVtbl[28]))(
(IDWriteFactory2*)Unsafe.AsPointer(ref this),
baselineOriginX,
baselineOriginY,
glyphRun,
glyphRunDescription,
measuringMode,
worldAndDpiTransform,
colorPaletteIndex,
colorLayers);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace MS.Internal.Text.TextInterface
{
/// <summary>
/// Represents a single color layer from a COLR v0 color glyph run decomposition.
/// </summary>
internal struct ColorGlyphLayer
{
public ushort[] GlyphIndices;
public float[] GlyphAdvances;
public float[] GlyphOffsets; // Interleaved (advanceOffset, ascenderOffset) pairs; may be null.
public float BaselineOriginX;
public float BaselineOriginY;
public float ColorR;
public float ColorG;
public float ColorB;
public float ColorA;
public bool UseForegroundColor;
}
}
Loading