/*
 * Copyright (C) 2004, 2005, 2006 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#pragma once

#include "WindRule.h"
#include <wtf/Forward.h>

namespace WTF {
class TextStream;
}

namespace WebCore {

enum CompositeOperator {
    CompositeClear,
    CompositeCopy,
    CompositeSourceOver,
    CompositeSourceIn,
    CompositeSourceOut,
    CompositeSourceAtop,
    CompositeDestinationOver,
    CompositeDestinationIn,
    CompositeDestinationOut,
    CompositeDestinationAtop,
    CompositeXOR,
    CompositePlusDarker,
    CompositePlusLighter,
    CompositeDifference
};

enum BlendMode {
    BlendModeNormal = 1, // Start with 1 to match SVG's blendmode enumeration.
    BlendModeMultiply,
    BlendModeScreen,
    BlendModeDarken,
    BlendModeLighten,
    BlendModeOverlay,
    BlendModeColorDodge,
    BlendModeColorBurn,
    BlendModeHardLight,
    BlendModeSoftLight,
    BlendModeDifference,
    BlendModeExclusion,
    BlendModeHue,
    BlendModeSaturation,
    BlendModeColor,
    BlendModeLuminosity,
    BlendModePlusDarker,
    BlendModePlusLighter
};

enum GradientSpreadMethod {
    SpreadMethodPad,
    SpreadMethodReflect,
    SpreadMethodRepeat
};

enum InterpolationQuality {
    InterpolationDefault,
    InterpolationNone,
    InterpolationLow,
    InterpolationMedium,
    InterpolationHigh
};

enum LineCap { ButtCap, RoundCap, SquareCap };

enum LineJoin { MiterJoin, RoundJoin, BevelJoin };

enum HorizontalAlignment { AlignLeft, AlignRight, AlignHCenter };

enum TextBaseline { AlphabeticTextBaseline, TopTextBaseline, MiddleTextBaseline, BottomTextBaseline, IdeographicTextBaseline, HangingTextBaseline };

enum TextAlign { StartTextAlign, EndTextAlign, LeftTextAlign, CenterTextAlign, RightTextAlign };

enum RenderingMode {
    Unaccelerated,
    UnacceleratedNonPlatformBuffer, // Use plain memory allocation rather than platform API to allocate backing store.
    Accelerated
};

enum class AlphaPremultiplication {
    Premultiplied,
    Unpremultiplied
};

String compositeOperatorName(CompositeOperator, BlendMode);
bool parseBlendMode(const String&, BlendMode&);
bool parseCompositeAndBlendOperator(const String&, CompositeOperator&, BlendMode&);

String textAlignName(TextAlign);
bool parseTextAlign(const String&, TextAlign&);

String textBaselineName(TextBaseline);
bool parseTextBaseline(const String&, TextBaseline&);

WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, BlendMode);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, CompositeOperator);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, WindRule);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, LineCap);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, LineJoin);
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, AlphaPremultiplication);

} // namespace WebCore

