/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkPDFFont_DEFINED
#define SkPDFFont_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "src/core/SkAdvancedTypefaceMetrics.h"
#include "src/core/SkStrikeCache.h"
#include "src/pdf/SkPDFGlyphUse.h"
#include "src/pdf/SkPDFTypes.h"

#include <vector>

class SkPDFDocument;
class SkString;

/** \class SkPDFFont
    A PDF Object class representing a font.  The font may have resources
    attached to it in order to embed the font.  SkPDFFonts are canonicalized
    so that resource deduplication will only include one copy of a font.
    This class uses the same pattern as SkPDFGraphicState, a static weak
    reference to each instantiated class.
*/
class SkPDFFont {
public:
    ~SkPDFFont();
    SkPDFFont(SkPDFFont&&);
    SkPDFFont& operator=(SkPDFFont&&);

    /** Returns the typeface represented by this class. Returns nullptr for the
     *  default typeface.
     */
    SkTypeface* typeface() const { return fTypeface.get(); }

    /** Returns the font type represented in this font.  For Type0 fonts,
     *  returns the type of the descendant font.
     */
    SkAdvancedTypefaceMetrics::FontType getType() const { return fFontType; }

    static SkAdvancedTypefaceMetrics::FontType FontType(const SkTypeface&,
                                                        const SkAdvancedTypefaceMetrics&);
    static void GetType1GlyphNames(const SkTypeface&, SkString*);

    static bool IsMultiByte(SkAdvancedTypefaceMetrics::FontType type) {
        return type == SkAdvancedTypefaceMetrics::kType1CID_Font ||
               type == SkAdvancedTypefaceMetrics::kTrueType_Font;
    }

    /** Returns true if this font encoding supports glyph IDs above 255.
     */
    bool multiByteGlyphs() const { return SkPDFFont::IsMultiByte(this->getType()); }

    /** Return true if this font has an encoding for the passed glyph id.
     */
    bool hasGlyph(SkGlyphID gid) {
        return (gid >= this->firstGlyphID() && gid <= this->lastGlyphID()) || gid == 0;
    }

    /** Convert the input glyph ID into the font encoding.  */
    SkGlyphID glyphToPDFFontEncoding(SkGlyphID gid) const {
        if (this->multiByteGlyphs() || gid == 0) {
            return gid;
        }
        SkASSERT(gid >= this->firstGlyphID() && gid <= this->lastGlyphID());
        SkASSERT(this->firstGlyphID() > 0);
        return gid - this->firstGlyphID() + 1;
    }

    void noteGlyphUsage(SkGlyphID glyph) {
        SkASSERT(this->hasGlyph(glyph));
        fGlyphUsage.set(glyph);
    }

    SkPDFIndirectReference indirectReference() const { return fIndirectReference; }

    /** Get the font resource for the passed typeface and glyphID. The
     *  reference count of the object is incremented and it is the caller's
     *  responsibility to unreference it when done.  This is needed to
     *  accommodate the weak reference pattern used when the returned object
     *  is new and has no other references.
     *  @param typeface  The typeface to find, not nullptr.
     *  @param glyphID   Specify which section of a large font is of interest.
     */
    static SkPDFFont* GetFontResource(SkPDFDocument* doc,
                                      const SkGlyph* glyphs,
                                      SkTypeface* typeface);

    /** Gets SkAdvancedTypefaceMetrics, and caches the result.
     *  @param typeface can not be nullptr.
     *  @return nullptr only when typeface is bad.
     */
    static const SkAdvancedTypefaceMetrics* GetMetrics(const SkTypeface* typeface,
                                                       SkPDFDocument* canon);

    static const std::vector<SkUnichar>& GetUnicodeMap(const SkTypeface* typeface,
                                                       SkPDFDocument* canon);

    static void PopulateCommonFontDescriptor(SkPDFDict* descriptor,
                                             const SkAdvancedTypefaceMetrics&,
                                             uint16_t emSize,
                                             int16_t defaultWidth);

    void emitSubset(SkPDFDocument*) const;

    /**
     *  Return false iff the typeface has its NotEmbeddable flag set.
     *  typeface is not nullptr
     */
    static bool CanEmbedTypeface(SkTypeface*, SkPDFDocument*);

    SkGlyphID firstGlyphID() const { return fGlyphUsage.firstNonZero(); }
    SkGlyphID lastGlyphID() const { return fGlyphUsage.lastGlyph(); }
    const SkPDFGlyphUse& glyphUsage() const { return fGlyphUsage; }
    sk_sp<SkTypeface> refTypeface() const { return fTypeface; }

private:
    sk_sp<SkTypeface> fTypeface;
    SkPDFGlyphUse fGlyphUsage;
    SkPDFIndirectReference fIndirectReference;
    SkAdvancedTypefaceMetrics::FontType fFontType;

    SkPDFFont(sk_sp<SkTypeface>,
              SkGlyphID firstGlyphID,
              SkGlyphID lastGlyphID,
              SkAdvancedTypefaceMetrics::FontType fontType,
              SkPDFIndirectReference indirectReference);
    // The glyph IDs accessible with this font.  For Type1 (non CID) fonts,
    // this will be a subset if the font has more than 255 glyphs.

    SkPDFFont() = delete;
    SkPDFFont(const SkPDFFont&) = delete;
    SkPDFFont& operator=(const SkPDFFont&) = delete;
};

#endif
