class CanvasTextFormat : RESOURCE_WRAPPER_RUNTIME_CLASS()

in winrt/lib/text/CanvasTextFormat.h [68:225]


    class CanvasTextFormat : RESOURCE_WRAPPER_RUNTIME_CLASS(
        IDWriteTextFormat1,
        CanvasTextFormat,
        ICanvasTextFormat,
        CloakedIid<ICanvasTextFormatInternal>)
    {
        InspectableClass(RuntimeClass_Microsoft_Graphics_Canvas_Text_CanvasTextFormat, BaseTrust);

        std::shared_ptr<CustomFontManager> m_customFontManager;

        //
        // Has Close() been called?  It is tempting to use a null resource to
        // indicated closed, but we need to be able to tell the difference
        // between not having created the resource yet and being closed.
        //
        bool m_closed;

        //
        // The various bits of shadow state and the realized format all need to
        // be updated atomically.
        //
        std::mutex m_mutex;
        
        //
        // Shadow properties.  These values are used to recreate the IDWriteTextFormat when
        // it is required.
        //
        ComPtr<IDWriteFontCollection> m_fontCollection;
        CanvasTextDirection m_direction;
        WinString m_fontFamilyName;
        float m_fontSize;
        ABI::Windows::UI::Text::FontStretch m_fontStretch;
        ABI::Windows::UI::Text::FontStyle m_fontStyle;
        ABI::Windows::UI::Text::FontWeight m_fontWeight;
        float m_incrementalTabStop;
        float m_lineSpacing;
        float m_lineSpacingBaseline;
        WinString m_localeName;
        CanvasVerticalAlignment m_verticalAlignment;
        CanvasHorizontalAlignment m_horizontalAlignment;
        CanvasTextTrimmingGranularity m_trimmingGranularity;
        WinString m_trimmingDelimiter;
        int32_t m_trimmingDelimiterCount;
        CanvasWordWrapping m_wordWrapping;
        CanvasVerticalGlyphOrientation m_verticalGlyphOrientation;
        CanvasOpticalAlignment m_opticalAlignment;
        bool m_lastLineWrapping;

        TrimmingSignInformation m_trimmingSignInformation;

        //
        // Draw text options are not part of IDWriteTextFormat, but are stored
        // in CanvasTextFormat.  These are not protected by the mutex since they
        // are independent from the shadow state / format.
        //
        CanvasDrawTextOptions m_drawTextOptions;

        //
        // This type is used on Win10, and is defined as a placeholder on 8.1.
        //
        CanvasLineSpacingMode m_lineSpacingMode;

    public:
        CanvasTextFormat();
        CanvasTextFormat(IDWriteTextFormat1* format);

        //
        // ICanvasTextFormat
        //
#define PROPERTY(NAME, TYPE)                            \
        IFACEMETHOD(get_##NAME)(TYPE* value) override;   \
        IFACEMETHOD(put_##NAME)(TYPE value) override

        PROPERTY(Direction,                CanvasTextDirection);
        PROPERTY(FontFamily,               HSTRING);
        PROPERTY(FontSize,                 float);
        PROPERTY(FontStretch,              ABI::Windows::UI::Text::FontStretch);
        PROPERTY(FontStyle,                ABI::Windows::UI::Text::FontStyle);
        PROPERTY(FontWeight,               ABI::Windows::UI::Text::FontWeight);
        PROPERTY(IncrementalTabStop,       float);
        PROPERTY(LineSpacing,              float);
        PROPERTY(LineSpacingBaseline,      float);
        PROPERTY(LocaleName,               HSTRING);
        PROPERTY(VerticalAlignment,        CanvasVerticalAlignment);
        PROPERTY(HorizontalAlignment,      CanvasHorizontalAlignment);
        PROPERTY(TrimmingGranularity,      CanvasTextTrimmingGranularity);
        PROPERTY(TrimmingDelimiter,        HSTRING);
        PROPERTY(TrimmingDelimiterCount,   int32_t);
        PROPERTY(WordWrapping,             CanvasWordWrapping);
        PROPERTY(Options,                  CanvasDrawTextOptions);
        PROPERTY(VerticalGlyphOrientation, CanvasVerticalGlyphOrientation);
        PROPERTY(OpticalAlignment,         CanvasOpticalAlignment);
        PROPERTY(LastLineWrapping,         boolean);
        PROPERTY(TrimmingSign,             CanvasTrimmingSign);
        PROPERTY(CustomTrimmingSign,       ICanvasTextInlineObject*);

#if WINVER > _WIN32_WINNT_WINBLUE
        PROPERTY(LineSpacingMode,          CanvasLineSpacingMode);
#endif

#undef PROPERTY

        //
        // IClosable
        //

        IFACEMETHOD(Close)() override;

        //
        // ICanvasTextFormatInternal
        //

        virtual ComPtr<IDWriteTextFormat1> GetRealizedTextFormat() override;
        virtual ComPtr<IDWriteTextFormat> GetRealizedTextFormatClone(CanvasWordWrapping overrideWordWrapping) override;
        virtual D2D1_DRAW_TEXT_OPTIONS GetDrawTextOptions() override;

        //
        // ICanvasResourceWrapperNative
        //
        
        IFACEMETHOD(GetNativeResource)(ICanvasDevice* device, float dpi, REFIID iid, void** resource) override;

    private:
        Lock GetLock()
        {
            return Lock(m_mutex);
        }
        
        void ThrowIfClosed();

        template<typename T, typename ST, typename FN>
        HRESULT __declspec(nothrow) PropertyGet(T* value, ST const& shadowValue, FN realizedGetter);

        template<typename T, typename TT, typename FNV>
        HRESULT __declspec(nothrow) PropertyPut(T value, TT* dest, FNV&& validator, void(CanvasTextFormat::*realizer)(IDWriteTextFormat1*) = nullptr);
        
        template<typename T, typename TT>
        HRESULT __declspec(nothrow) PropertyPut(T value, TT* dest, void(CanvasTextFormat::*realizer)(IDWriteTextFormat1*) = nullptr);

        void SetShadowPropertiesFromDWrite();

        void Unrealize();

        void RealizeDirection(IDWriteTextFormat1* textFormat);
        void RealizeIncrementalTabStop(IDWriteTextFormat1* textFormat);
        void RealizeLineSpacing(IDWriteTextFormat1* textFormat);
        void RealizeParagraphAlignment(IDWriteTextFormat1* textFormat);
        void RealizeTextAlignment(IDWriteTextFormat1* textFormat);
        void RealizeTrimming(IDWriteTextFormat1* textFormat);
        void RealizeWordWrapping(IDWriteTextFormat1* textFormat);
        void RealizeVerticalGlyphOrientation(IDWriteTextFormat1* textFormat);
        void RealizeOpticalAlignment(IDWriteTextFormat1* textFormat);
        void RealizeLastLineWrapping(IDWriteTextFormat1* textFormat);
        void RealizeTrimmingSign(IDWriteTextFormat1* textFormat);
        void RealizeCustomTrimmingSign(IDWriteTextFormat1* textFormat);

        ComPtr<IDWriteTextFormat1> CreateRealizedTextFormat(bool skipWordWrapping = false);
};