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

#include "GrPathRendering.h"
#include "SkDescriptor.h"
#include "SkGlyph.h"
#include "SkMatrix.h"
#include "SkTypeface.h"
#include "GrPathRange.h"

class GlyphGenerator : public GrPathRange::PathGenerator {
public:
    GlyphGenerator(const SkTypeface& typeface, const SkDescriptor& desc)
        : fScalerContext(typeface.createScalerContext(&desc))
#ifdef SK_DEBUG
        , fDesc(desc.copy())
#endif
    {}

    virtual ~GlyphGenerator() {
#ifdef SK_DEBUG
        SkDescriptor::Free(fDesc);
#endif
    }

    int getNumPaths() override {
        return fScalerContext->getGlyphCount();
    }

    void generatePath(int glyphID, SkPath* out) override {
        SkGlyph skGlyph;
        skGlyph.initWithGlyphID(glyphID);
        fScalerContext->getMetrics(&skGlyph);

        fScalerContext->getPath(skGlyph, out);
    }
#ifdef SK_DEBUG
    bool isEqualTo(const SkDescriptor& desc) const override {
        return fDesc->equals(desc);
    }
#endif
private:
    const SkAutoTDelete<SkScalerContext> fScalerContext;
#ifdef SK_DEBUG
    SkDescriptor* const fDesc;
#endif
};

GrPathRange* GrPathRendering::createGlyphs(const SkTypeface* typeface,
                                           const SkDescriptor* desc,
                                           const GrStrokeInfo& stroke) {
    if (nullptr == typeface) {
        typeface = SkTypeface::GetDefaultTypeface();
        SkASSERT(nullptr != typeface);
    }

    if (desc) {
        SkAutoTUnref<GlyphGenerator> generator(new GlyphGenerator(*typeface, *desc));
        return this->createPathRange(generator, stroke);
    }

    SkScalerContextRec rec;
    memset(&rec, 0, sizeof(rec));
    rec.fFontID = typeface->uniqueID();
    rec.fTextSize = SkPaint::kCanonicalTextSizeForPaths;
    rec.fPreScaleX = rec.fPost2x2[0][0] = rec.fPost2x2[1][1] = SK_Scalar1;
    // Don't bake stroke information into the glyphs, we'll let the GPU do the stroking.

    SkAutoDescriptor ad(sizeof(rec) + SkDescriptor::ComputeOverhead(1));
    SkDescriptor*    genericDesc = ad.getDesc();

    genericDesc->init();
    genericDesc->addEntry(kRec_SkDescriptorTag, sizeof(rec), &rec);
    genericDesc->computeChecksum();

    SkAutoTUnref<GlyphGenerator> generator(new GlyphGenerator(*typeface, *genericDesc));
    return this->createPathRange(generator, stroke);
}
