
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SampleCode.h"
#include "SkView.h"
#include "SkCanvas.h"
#include "SkGraphics.h"
#include "SkRandom.h"

#include <pthread.h>

static void call_measure() {
    SkPaint paint;
    uint16_t text[32];
    SkRandom rand;

    paint.setAntiAlias(true);
    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);

    for (int i = 9; i < 36; i++) {
        SkPaint::FontMetrics m;

        paint.setTextSize(SkIntToScalar(i));
        paint.getFontMetrics(&m);
        paint.measureText(text, sizeof(text));
    }
}

static void call_draw(SkCanvas* canvas) {
    SkPaint paint;
    uint16_t text[32];
    SkRandom rand;

    paint.setAntiAlias(true);
    paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
    for (int j = 0; j < SK_ARRAY_COUNT(text); j++)
        text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32);

    SkScalar x = SkIntToScalar(10);
    SkScalar y = SkIntToScalar(20);

    canvas->drawColor(SK_ColorWHITE);
    for (int i = 9; i < 36; i++)
    {
        SkPaint::FontMetrics m;

        paint.setTextSize(SkIntToScalar(i));
        paint.getFontMetrics(&m);
        canvas->drawText(text, sizeof(text), x, y, paint);
        y += m.fDescent - m.fAscent;
    }
}

static bool gDone;

static void* measure_proc(void* context) {
    while (!gDone) {
        call_measure();
    }
    return NULL;
}

static void* draw_proc(void* context) {
    SkBitmap* bm = (SkBitmap*)context;
    SkCanvas    canvas(*bm);

    while (!gDone) {
        call_draw(&canvas);
    }
    return NULL;
}

class FontCacheView : public SampleView {
public:
    enum { N = 4 };

    pthread_t   fMThreads[N];
    pthread_t   fDThreads[N];
    SkBitmap    fBitmaps[N];

    FontCacheView() {
        gDone = false;
        for (int i = 0; i < N; i++) {
            int status;

            status = pthread_create(&fMThreads[i], NULL,  measure_proc, NULL);
            SkASSERT(0 == status);

            fBitmaps[i].allocPixels(SkImageInfo::Make(320, 240,
                                                      kRGB_565_SkColorType,
                                                      kOpaque_SkAlphaType));
            status = pthread_create(&fDThreads[i], NULL,  draw_proc, &fBitmaps[i]);
            SkASSERT(0 == status);
        }
        this->setBGColor(0xFFDDDDDD);
    }

    virtual ~FontCacheView() {
        gDone = true;
        for (int i = 0; i < N; i++) {
            void* ret;
            int status = pthread_join(fMThreads[i], &ret);
            SkASSERT(0 == status);
            status = pthread_join(fDThreads[i], &ret);
            SkASSERT(0 == status);
        }
    }

protected:
    // overrides from SkEventSink
    virtual bool onQuery(SkEvent* evt) {
        if (SampleCode::TitleQ(*evt)) {
            SampleCode::TitleR(evt, "FontCache");
            return true;
        }
        return this->INHERITED::onQuery(evt);
    }

    virtual void onDrawContent(SkCanvas* canvas) {
        SkScalar x = 0;
        SkScalar y = 0;
        for (int i = 0; i < N; i++) {
            canvas->drawBitmap(fBitmaps[i], x, y);
            x += SkIntToScalar(fBitmaps[i].width());
        }
        this->inval(NULL);
    }

private:
    typedef SampleView INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() { return new FontCacheView; }
static SkViewRegister reg(MyFactory);
