/*
 * Copyright 2014 Nikolay Sivov for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "dwrite_1.idl";

typedef enum DWRITE_OPTICAL_ALIGNMENT
{
    DWRITE_OPTICAL_ALIGNMENT_NONE,
    DWRITE_OPTICAL_ALIGNMENT_NO_SIDE_BEARINGS
} DWRITE_OPTICAL_ALIGNMENT;

typedef enum DWRITE_GRID_FIT_MODE
{
    DWRITE_GRID_FIT_MODE_DEFAULT,
    DWRITE_GRID_FIT_MODE_DISABLED,
    DWRITE_GRID_FIT_MODE_ENABLED
} DWRITE_GRID_FIT_MODE;

typedef struct DWRITE_TEXT_METRICS1
{
    /* DWRITE_TEXT_METRICS fields */
    FLOAT left;
    FLOAT top;
    FLOAT width;
    FLOAT widthIncludingTrailingWhitespace;
    FLOAT height;
    FLOAT layoutWidth;
    FLOAT layoutHeight;
    UINT32 maxBidiReorderingDepth;
    UINT32 lineCount;
    /* DWRITE_TEXT_METRICS1 fields */
    FLOAT heightIncludingTrailingWhitespace;
} DWRITE_TEXT_METRICS1;

cpp_quote("#ifndef D3DCOLORVALUE_DEFINED")
typedef struct _D3DCOLORVALUE
{
    union {
        FLOAT r;
        FLOAT dvR;
    };
    union {
        FLOAT g;
        FLOAT dvG;
    };
    union {
        FLOAT b;
        FLOAT dvB;
    };
    union {
        FLOAT a;
        FLOAT dvA;
    };
} D3DCOLORVALUE;
cpp_quote("#define D3DCOLORVALUE_DEFINED")
cpp_quote("#endif")

typedef D3DCOLORVALUE DWRITE_COLOR_F;

typedef struct DWRITE_COLOR_GLYPH_RUN
{
    DWRITE_GLYPH_RUN glyphRun;
    DWRITE_GLYPH_RUN_DESCRIPTION* glyphRunDescription;
    FLOAT baselineOriginX;
    FLOAT baselineOriginY;
    DWRITE_COLOR_F runColor;
    UINT16 paletteIndex;
} DWRITE_COLOR_GLYPH_RUN;

[
    local,
    object,
    uuid(d3e0e934-22a0-427e-aae4-7d9574b59db1)
]
interface IDWriteTextRenderer1 : IDWriteTextRenderer
{
    HRESULT DrawGlyphRun(void *context,
                         FLOAT originX,
                         FLOAT originY,
                         DWRITE_GLYPH_ORIENTATION_ANGLE angle,
                         DWRITE_MEASURING_MODE mode,
                         DWRITE_GLYPH_RUN const *run,
                         DWRITE_GLYPH_RUN_DESCRIPTION const *rundescr,
                         IUnknown *effect);

    HRESULT DrawUnderline(void *context,
                          FLOAT originX,
                          FLOAT originY,
                          DWRITE_GLYPH_ORIENTATION_ANGLE angle,
                          DWRITE_UNDERLINE const *underline,
                          IUnknown *effect);

    HRESULT DrawStrikethrough(void *context,
                              FLOAT originX,
                              FLOAT originY,
                              DWRITE_GLYPH_ORIENTATION_ANGLE angle,
                              DWRITE_STRIKETHROUGH const *strikethrough,
                              IUnknown *effect
                             );

    HRESULT DrawInlineObject(void *context,
                             FLOAT originX,
                             FLOAT originY,
                             DWRITE_GLYPH_ORIENTATION_ANGLE angle,
                             IDWriteInlineObject *inlineObject,
                             BOOL is_sideways,
                             BOOL is_rtl,
                             IUnknown *effect
                            );
}

[
    local,
    object,
    uuid(efa008f9-f7a1-48bf-b05c-f224713cc0ff)
]
interface IDWriteFontFallback : IUnknown
{
    HRESULT MapCharacters(IDWriteTextAnalysisSource *source,
                          UINT32 position,
                          UINT32 length,
                          IDWriteFontCollection *basecollection,
                          const WCHAR *baseFamilyName,
                          DWRITE_FONT_WEIGHT baseWeight,
                          DWRITE_FONT_STYLE baseStyle,
                          DWRITE_FONT_STRETCH baseStretch,
                          UINT32 *mappedLength,
                          IDWriteFont **mappedFont,
                          FLOAT *scale
                         );
}

[
    local,
    object,
    uuid(5f174b49-0d8b-4cfb-8bca-f1cce9d06c67)
]
interface IDWriteTextFormat1 : IDWriteTextFormat
{
    HRESULT SetVerticalGlyphOrientation(DWRITE_VERTICAL_GLYPH_ORIENTATION orientation);
    DWRITE_VERTICAL_GLYPH_ORIENTATION GetVerticalGlyphOrientation();
    HRESULT SetLastLineWrapping(BOOL lastline_wrapping_enabled);
    BOOL GetLastLineWrapping();
    HRESULT SetOpticalAlignment(DWRITE_OPTICAL_ALIGNMENT alignment);
    DWRITE_OPTICAL_ALIGNMENT GetOpticalAlignment();
    HRESULT SetFontFallback(IDWriteFontFallback *fallback);
    HRESULT GetFontFallback(IDWriteFontFallback **fallback);
}

[
    local,
    object,
    uuid(1093c18f-8d5e-43f0-b064-0917311b525e)
]
interface IDWriteTextLayout2 : IDWriteTextLayout1
{
    HRESULT GetMetrics(DWRITE_TEXT_METRICS1 *metrics);
    HRESULT SetVerticalGlyphOrientation(DWRITE_VERTICAL_GLYPH_ORIENTATION orientation);
    DWRITE_VERTICAL_GLYPH_ORIENTATION GetVerticalGlyphOrientation();
    HRESULT SetLastLineWrapping(BOOL lastline_wrapping_enabled);
    BOOL GetLastLineWrapping();
    HRESULT SetOpticalAlignment(DWRITE_OPTICAL_ALIGNMENT alignment);
    DWRITE_OPTICAL_ALIGNMENT GetOpticalAlignment();
    HRESULT SetFontFallback(IDWriteFontFallback *fallback);
    HRESULT GetFontFallback(IDWriteFontFallback **fallback);
}

[
    local,
    object,
    uuid(553a9ff3-5693-4df7-b52b-74806f7f2eb9)
]
interface IDWriteTextAnalyzer2 : IDWriteTextAnalyzer1
{
    HRESULT GetGlyphOrientationTransform(DWRITE_GLYPH_ORIENTATION_ANGLE angle,
                                         BOOL is_sideways,
                                         FLOAT originX,
                                         FLOAT originY,
                                         DWRITE_MATRIX *transform
                                        );
    HRESULT GetTypographicFeatures(IDWriteFontFace *fontface,
                                   DWRITE_SCRIPT_ANALYSIS analysis,
                                   const WCHAR *localeName,
                                   UINT32 max_tagcount,
                                   UINT32 *actual_tagcount,
                                   DWRITE_FONT_FEATURE_TAG *tags
                                  );

    HRESULT CheckTypographicFeature(IDWriteFontFace *fontface,
                                    DWRITE_SCRIPT_ANALYSIS analysis,
                                    const WCHAR *localeName,
                                    DWRITE_FONT_FEATURE_TAG feature,
                                    UINT32 glyph_count,
                                    const UINT16 *indices,
                                    UINT8 *feature_applies
                                   );
}

[
    local,
    object,
    uuid(fd882d06-8aba-4fb8-b849-8be8b73e14de)
]
interface IDWriteFontFallbackBuilder : IUnknown
{
    HRESULT AddMapping(const DWRITE_UNICODE_RANGE *ranges,
                       UINT32 rangesCount,
                       WCHAR const **targetFamilyNames,
                       UINT32 targetFamilyNamesCount,
                       [defaultvalue(NULL)] IDWriteFontCollection *collection,
                       [defaultvalue(NULL)] WCHAR const *localeName,
                       [defaultvalue(NULL)] WCHAR const *baseFamilyName,
                       [defaultvalue(1)] FLOAT scale
                      );
    HRESULT AddMappings(IDWriteFontFallback *fallback);
    HRESULT CreateFontFallback(IDWriteFontFallback **fallback);
}

[
    local,
    object,
    uuid(29748ed6-8c9c-4a6a-be0b-d912e8538944)
]
interface IDWriteFont2 : IDWriteFont1
{
    BOOL IsColorFont();
}

[
    local,
    object,
    uuid(d8b768ff-64bc-4e66-982b-ec8e87f693f7)
]
interface IDWriteFontFace2 : IDWriteFontFace1
{
    BOOL IsColorFont();
    UINT32 GetColorPaletteCount();
    UINT32 GetPaletteEntryCount();
    HRESULT GetPaletteEntries(UINT32 palette_index,
                              UINT32 first_entry_index,
                              UINT32 entry_count,
                              DWRITE_COLOR_F *entries
                             );
    HRESULT GetRecommendedRenderingMode(FLOAT fontEmSize,
                                        FLOAT dpiX,
                                        FLOAT dpiY,
                                        DWRITE_MATRIX const *transform,
                                        BOOL is_sideways,
                                        DWRITE_OUTLINE_THRESHOLD threshold,
                                        DWRITE_MEASURING_MODE measuringmode,
                                        IDWriteRenderingParams *params,
                                        DWRITE_RENDERING_MODE *renderingmode,
                                        DWRITE_GRID_FIT_MODE *gridfitmode
                                       );
}

[
    local,
    object,
    uuid(d31fbe17-f157-41a2-8d24-cb779e0560e8)
]
interface IDWriteColorGlyphRunEnumerator : IUnknown
{
    HRESULT MoveNext(BOOL *hasRun);
    HRESULT GetCurrentRun(DWRITE_COLOR_GLYPH_RUN const **run);
}

[
    local,
    object,
    uuid(f9d711c3-9777-40ae-87e8-3e5aF9bf0948)
]
interface IDWriteRenderingParams2 : IDWriteRenderingParams1
{
    DWRITE_GRID_FIT_MODE GetGridFitMode();
}

[
    local,
    object,
    uuid(0439fc60-ca44-4994-8dee-3a9af7b732ec)
]
interface IDWriteFactory2 : IDWriteFactory1
{
    HRESULT GetSystemFontFallback(IDWriteFontFallback **fallback);
    HRESULT CreateFontFallbackBuilder(IDWriteFontFallbackBuilder **fallbackbuilder);
    HRESULT TranslateColorGlyphRun(FLOAT originX,
                                   FLOAT originY,
                                   const DWRITE_GLYPH_RUN *run,
                                   const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr,
                                   DWRITE_MEASURING_MODE mode,
                                   const DWRITE_MATRIX *transform,
                                   UINT32 palette_index,
                                   IDWriteColorGlyphRunEnumerator **colorlayers
                                  );

    HRESULT CreateCustomRenderingParams(FLOAT gamma,
                                        FLOAT contrast,
                                        FLOAT grayscalecontrast,
                                        FLOAT cleartypeLevel,
                                        DWRITE_PIXEL_GEOMETRY pixelGeometry,
                                        DWRITE_RENDERING_MODE renderingMode,
                                        DWRITE_GRID_FIT_MODE gridFitMode,
                                        IDWriteRenderingParams2 **params
                                       );

    HRESULT CreateGlyphRunAnalysis(const DWRITE_GLYPH_RUN *run,
                                   const DWRITE_MATRIX *transform,
                                   DWRITE_RENDERING_MODE renderingMode,
                                   DWRITE_MEASURING_MODE measuringMode,
                                   DWRITE_GRID_FIT_MODE gridFitMode,
                                   DWRITE_TEXT_ANTIALIAS_MODE antialiasMode,
                                   FLOAT originX,
                                   FLOAT originY,
                                   IDWriteGlyphRunAnalysis **analysis
                                  );
}
