/*
 * Copyright (C) 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SkAdvancedTypefaceMetrics.h"
#include "SkTypes.h"

#ifdef SK_BUILD_FOR_UNIX
#include <ft2build.h>
#include FT_FREETYPE_H
#endif

namespace skia_advanced_typeface_metrics_utils {

template <typename Data>
void resetRange(SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
                int startId) {
    range->fStartId = startId;
    range->fAdvance.setCount(0);
}

template <typename Data>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* appendRange(
        SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> >* nextSlot,
        int startId) {
    nextSlot->reset(new SkAdvancedTypefaceMetrics::AdvanceMetric<Data>);
    resetRange(nextSlot->get(), startId);
    return nextSlot->get();
}

template <typename Data>
void finishRange(
        SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* range,
        int endId,
        typename SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::MetricType
                type) {
    range->fEndId = endId;
    range->fType = type;
    int newLength;
    if (type == SkAdvancedTypefaceMetrics::AdvanceMetric<Data>::kRange) {
        newLength = endId - range->fStartId + 1;
    } else {
        newLength = 1;
    }
    SkASSERT(range->fAdvance.count() >= newLength);
    range->fAdvance.setCount(newLength);
}

template <typename Data, typename FontHandle>
SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* getAdvanceData(
        FontHandle fontHandle,
        int num_glyphs,
        bool (*getAdvance)(FontHandle fontHandle, int gId, Data* data)) {
    // Assuming that an ASCII representation of a width or a glyph id is,
    // on average, 3 characters long gives the following cut offs for
    // using different range types:
    // When currently in a range
    //  - Removing 4 0's is a win
    //  - Removing 5 repeats is a win
    // When not currently in a range
    //  - Removing 1 0 is a win
    //  - Removing 3 repeats is a win

    SkTScopedPtr<SkAdvancedTypefaceMetrics::AdvanceMetric<Data> > result;
    SkAdvancedTypefaceMetrics::AdvanceMetric<Data>* curRange;
    curRange = appendRange(&result, 0);
    Data lastAdvance = SK_MinS16;
    int repeats = 0;
    for (int gId = 0; gId < num_glyphs; gId++) {
        Data advance;
        if (!getAdvance(fontHandle, gId, &advance)) {
            num_glyphs = (gId > 0) ? gId - 1 : 0;
            break;
        }
        if (advance == lastAdvance) {
            repeats++;
        } else if (curRange->fAdvance.count() == repeats + 1) {
            if (lastAdvance == 0 && repeats >= 0) {
                resetRange(curRange, gId);
            } else if (repeats >= 2) {
                finishRange(curRange, gId - 1,
                            SkAdvancedTypefaceMetrics::WidthRange::kRun);
                curRange = appendRange(&curRange->fNext, gId);
            }
            repeats = 0;
        } else {
            if (lastAdvance == 0 && repeats >= 3) {
                finishRange(curRange, gId - repeats - 2,
                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
                curRange = appendRange(&curRange->fNext, gId);
            } else if (repeats >= 4) {
                finishRange(curRange, gId - repeats - 2,
                            SkAdvancedTypefaceMetrics::WidthRange::kRange);
                curRange = appendRange(&curRange->fNext, gId - repeats - 1);
                curRange->fAdvance.append(1, &lastAdvance);
                finishRange(curRange, gId - 1,
                            SkAdvancedTypefaceMetrics::WidthRange::kRun);
                curRange = appendRange(&curRange->fNext, gId);
            }
            repeats = 0;
        }
        curRange->fAdvance.append(1, &advance);
        lastAdvance = advance;
    }
    finishRange(curRange, num_glyphs - 1,
                SkAdvancedTypefaceMetrics::WidthRange::kRange);
    return result.release();
}

// Make AdvanceMetric template functions available for linking with typename
// WidthRange and VerticalAdvanceRange.
#if defined(SK_BUILD_FOR_WIN)
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
        HDC hdc,
        int num_glyphs,
        bool (*getAdvance)(HDC hdc, int gId, int16_t* data));
#elif defined(SK_BUILD_FOR_UNIX)
template SkAdvancedTypefaceMetrics::WidthRange* getAdvanceData(
        FT_Face face,
        int num_glyphs,
        bool (*getAdvance)(FT_Face face, int gId, int16_t* data));
#endif
template void resetRange(
        SkAdvancedTypefaceMetrics::WidthRange* range,
        int startId);
template SkAdvancedTypefaceMetrics::WidthRange* appendRange(
        SkTScopedPtr<SkAdvancedTypefaceMetrics::WidthRange >* nextSlot,
        int startId);
template void finishRange<int16_t>(
        SkAdvancedTypefaceMetrics::WidthRange* range,
        int endId,
        SkAdvancedTypefaceMetrics::WidthRange::MetricType type);

template void resetRange(
        SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
        int startId);
template SkAdvancedTypefaceMetrics::VerticalAdvanceRange* appendRange(
        SkTScopedPtr<SkAdvancedTypefaceMetrics::VerticalAdvanceRange >*
            nextSlot,
        int startId);
template void finishRange<SkAdvancedTypefaceMetrics::VerticalMetric>(
        SkAdvancedTypefaceMetrics::VerticalAdvanceRange* range,
        int endId,
        SkAdvancedTypefaceMetrics::VerticalAdvanceRange::MetricType type);

} // namespace skia_advanced_typeface_metrics_utils
