/*
 * Copyright (C) 2011 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#pragma once

#include "FontCascade.h"
#include "RenderText.h"
#include "Text.h"

namespace WebCore {

class RenderCombineText final : public RenderText {
    WTF_MAKE_ISO_ALLOCATED(RenderCombineText);
public:
    RenderCombineText(Text&, const String&);

    Text& textNode() const { return downcast<Text>(nodeForNonAnonymous()); }

    void combineTextIfNeeded();
    Optional<FloatPoint> computeTextOrigin(const FloatRect& boxRect) const;
    String combinedStringForRendering() const;
    bool isCombined() const { return m_isCombined; }
    float combinedTextWidth(const FontCascade& font) const { return font.size(); }
    const FontCascade& originalFont() const { return parent()->style().fontCascade(); }
    const FontCascade& textCombineFont() const { return m_combineFontStyle->fontCascade(); }

private:
    void node() const = delete;

    bool isCombineText() const override { return true; }
    float width(unsigned from, unsigned length, const FontCascade&, float xPosition, HashSet<const Font*>* fallbackFonts = 0, GlyphOverflow* = 0) const override;
    const char* renderName() const override { return "RenderCombineText"; }
    void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
    void setRenderedText(const String&) override;

    std::unique_ptr<RenderStyle> m_combineFontStyle;
    float m_combinedTextWidth { 0 };
    float m_combinedTextAscent { 0 };
    float m_combinedTextDescent { 0 };
    bool m_isCombined : 1;
    bool m_needsFontUpdate : 1;
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderCombineText, isCombineText())
