<commit_before>#include "SampleApp.h"

#include "SkData.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGpuDevice.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTime.h"
#include "SkWindow.h"

#include "SampleCode.h"
#include "GrContext.h"
#include "SkTypeface.h"

#include "GrGLInterface.h"

#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
#include "SkStream.h"

#define TEST_GPIPEx

#ifdef  TEST_GPIPE
#define PIPE_FILE
#define FILE_PATH "/path/to/drawing.data"
#endif

#define USE_ARROWS_FOR_ZOOM true
//#define DEFAULT_TO_GPU

extern SkView* create_overview(int, const SkViewFactory[]);

#define SK_SUPPORT_GL

#define ANIMATING_EVENTTYPE "nextSample"
#define ANIMATING_DELAY     750

#ifdef SK_DEBUG
    #define FPS_REPEAT_MULTIPLIER   1
#else
    #define FPS_REPEAT_MULTIPLIER   10
#endif
#define FPS_REPEAT_COUNT    (10 * FPS_REPEAT_MULTIPLIER)

#ifdef SK_SUPPORT_GL
    #include "GrGLConfig.h"
#endif

static SampleWindow* gSampleWindow;

///////////////
static const char view_inval_msg[] = "view-inval-msg";

void SampleWindow::postInvalDelay() {
    SkEvent* evt = new SkEvent(view_inval_msg);
    evt->post(this->getSinkID(), 1);
}

static bool isInvalEvent(const SkEvent& evt) {
    return evt.isType(view_inval_msg);
}
//////////////////

SkViewRegister* SkViewRegister::gHead;
SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
    static bool gOnce;
    if (!gOnce) {
        gHead = NULL;
        gOnce = true;
    }

    fChain = gHead;
    gHead = this;
}

#if defined(SK_SUPPORT_GL)
    #define SK_USE_SHADERS
#endif

#if 0
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFURLAccess.h>

static void testpdf() {
    CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
                                                 kCFStringEncodingUTF8);
    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
                                              kCFURLPOSIXPathStyle,
                                              false);
    CFRelease(path);
    CGRect box = CGRectMake(0, 0, 8*72, 10*72);
    CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
    CFRelease(url);

    CGContextBeginPage(cg, &box);
    CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
    CGContextFillEllipseInRect(cg, r);
    CGContextEndPage(cg);
    CGContextRelease(cg);

    if (false) {
        SkBitmap bm;
        bm.setConfig(SkBitmap::kA8_Config, 64, 64);
        bm.allocPixels();
        bm.eraseColor(0);

        SkCanvas canvas(bm);

    }
}
#endif

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

enum FlipAxisEnum {
    kFlipAxis_X = (1 << 0),
    kFlipAxis_Y = (1 << 1)
};

static SkTriState cycle_tristate(SkTriState state) {
    static const SkTriState gCycle[] = {
        /* kFalse_SkTriState   -> */  kUnknown_SkTriState,
        /* kTrue_SkTriState    -> */  kFalse_SkTriState,
        /* kUnknown_SkTriState -> */  kTrue_SkTriState,
    };
    return gCycle[state];
}

#include "SkDrawFilter.h"

class FlagsDrawFilter : public SkDrawFilter {
public:
    FlagsDrawFilter(SkTriState lcd, SkTriState aa, SkTriState filter,
                    SkTriState hinting) :
        fLCDState(lcd), fAAState(aa), fFilterState(filter), fHintingState(hinting) {}

    virtual void filter(SkPaint* paint, Type t) {
        if (kText_Type == t && kUnknown_SkTriState != fLCDState) {
            paint->setLCDRenderText(kTrue_SkTriState == fLCDState);
        }
        if (kUnknown_SkTriState != fAAState) {
            paint->setAntiAlias(kTrue_SkTriState == fAAState);
        }
        if (kUnknown_SkTriState != fFilterState) {
            paint->setFilterBitmap(kTrue_SkTriState == fFilterState);
        }
        if (kUnknown_SkTriState != fHintingState) {
            paint->setHinting(kTrue_SkTriState == fHintingState ?
                              SkPaint::kNormal_Hinting :
                              SkPaint::kSlight_Hinting);
        }
    }

private:
    SkTriState  fLCDState;
    SkTriState  fAAState;
    SkTriState  fFilterState;
    SkTriState  fHintingState;
};

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

#define MAX_ZOOM_LEVEL  8
#define MIN_ZOOM_LEVEL  -8

static const char gCharEvtName[] = "SampleCode_Char_Event";
static const char gKeyEvtName[] = "SampleCode_Key_Event";
static const char gTitleEvtName[] = "SampleCode_Title_Event";
static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
static const char gFastTextEvtName[] = "SampleCode_FastText_Event";

bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
        if (outUni) {
            *outUni = evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
        if (outKey) {
            *outKey = (SkKey)evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::TitleQ(const SkEvent& evt) {
    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
}

void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    SkASSERT(evt && TitleQ(*evt));
    evt->setString(gTitleEvtName, title);
}

bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
}

void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
    SkASSERT(evt && PrefSizeQ(*evt));
    SkScalar size[2];
    size[0] = width;
    size[1] = height;
    evt->setScalars(gPrefSizeEvtName, 2, size);
}

bool SampleCode::FastTextQ(const SkEvent& evt) {
    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
}

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

static SkMSec gAnimTime;
static SkMSec gAnimTimePrev;

SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
SkScalar SampleCode::GetAnimSecondsDelta() {
    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
}

SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
    // since gAnimTime can be up to 32 bits, we can't convert it to a float
    // or we'll lose the low bits. Hence we use doubles for the intermediate
    // calculations
    double seconds = (double)gAnimTime / 1000.0;
    double value = SkScalarToDouble(speed) * seconds;
    if (period) {
        value = ::fmod(value, SkScalarToDouble(period));
    }
    return SkDoubleToScalar(value);
}

GrContext* SampleCode::GetGr() {
    return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
}

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

static SkView* curr_view(SkWindow* wind) {
    SkView::F2BIter iter(wind);
    return iter.next();
}

void SampleWindow::setZoomCenter(float x, float y)
{
    fZoomCenterX = SkFloatToScalar(x);
    fZoomCenterY = SkFloatToScalar(y);
}

bool SampleWindow::setGrContext(GrContext* context)
{
    if (fGrContext) {
        fGrContext->unref();
    }
    fGrContext = context;
    fGrContext->ref();
    return true;
}

GrContext* SampleWindow::getGrContext()
{
    return fGrContext;
}

bool SampleWindow::zoomIn()
{
    // Arbitrarily decided
    if (fFatBitsScale == 25) return false;
    fFatBitsScale++;
    this->inval(NULL);
    return true;
}

bool SampleWindow::zoomOut()
{
    if (fFatBitsScale == 1) return false;
    fFatBitsScale--;
    this->inval(NULL);
    return true;
}

void SampleWindow::toggleZoomer()
{
    fShowZoomer = !fShowZoomer;
    this->inval(NULL);
}

void SampleWindow::updatePointer(int x, int y)
{
    fMouseX = x;
    fMouseY = y;
    if (fShowZoomer) {
        this->inval(NULL);
    }
}

bool SampleWindow::make3DReady() {

#if defined(SK_SUPPORT_GL)
    if (attachGL()) {
        if (NULL != fGrContext) {
        // various gr lifecycle tests
        #if   0
            fGrContext->freeGpuResources();
        #elif 0
            // this will leak resources.
            fGrContext->contextLost();
        #elif 0
            GrAssert(1 == fGrContext->refcnt());
            fGrContext->unref();
            fGrContext = NULL;
        #endif
        }

        if (NULL == fGrContext) {
        #if defined(SK_USE_SHADERS)
            fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
        #else
            fGrContext = GrContext::Create(kOpenGL_Fixed_GrEngine, NULL);
        #endif
            SkDebugf("---- constructor\n");
        }

        if (NULL != fGrContext) {
            return true;
        } else {
            detachGL();
        }
    }
#endif
    SkDebugf("Failed to setup 3D");
    return false;
}

SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
    static const CanvasType gCT[] = {
        kPicture_CanvasType,
        kGPU_CanvasType,
        kRaster_CanvasType
    };
    return gCT[ct];
}

SampleWindow::SampleWindow(void* hwnd, int argc, char** argv) : INHERITED(hwnd) {
    gSampleWindow = this;

#ifdef  PIPE_FILE
    //Clear existing file or create file if it doesn't exist
    FILE* f = fopen(FILE_PATH, "wb");
    fclose(f);
#endif
     
    fPicture = NULL;

    fGrContext = NULL;
    fGrRenderTarget = NULL;

#ifdef DEFAULT_TO_GPU
    fCanvasType = kGPU_CanvasType;
#else
    fCanvasType = kRaster_CanvasType;
#endif
    fUseClip = false;
    fNClip = false;
    fRepeatDrawing = false;
    fAnimating = false;
    fRotate = false;
    fScale = false;
    fRequestGrabImage = false;
    fUsePipe = false;
    fMeasureFPS = false;
    fLCDState = kUnknown_SkTriState;
    fAAState = kUnknown_SkTriState;
    fFilterState = kUnknown_SkTriState;
    fHintingState = kUnknown_SkTriState;
    fFlipAxis = 0;
    fScrollTestX = fScrollTestY = 0;

    fMouseX = fMouseY = 0;
    fFatBitsScale = 8;
    fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
    fShowZoomer = false;

    fZoomLevel = 0;
    fZoomScale = SK_Scalar1;

    fSaveToPdf = false;
    fPdfCanvas = NULL;

//    this->setConfig(SkBitmap::kRGB_565_Config);
    this->setConfig(SkBitmap::kARGB_8888_Config);
    this->setVisibleP(true);
    this->setClipToBounds(false);

    {
        const SkViewRegister* reg = SkViewRegister::Head();
        while (reg) {
            *fSamples.append() = reg->factory();
            reg = reg->next();
        }
    }
    fCurrIndex = 0;
    if (argc > 1) {
        int i, count = fSamples.count();
        for (i = 0; i < count; i++) {
            SkString title = getSampleTitle(i);
            if (title.equals(argv[1])) {
                fCurrIndex = i;
                break;
            }
        }
        if (i == count) {
            fprintf(stderr, "Unknown sample \"%s\"\n", argv[1]);
        }
    }
    this->loadView(fSamples[fCurrIndex]());

    // If another constructor set our dimensions, ensure that our
    // onSizeChange gets called.
    if (this->height() && this->width()) {
        this->onSizeChange();
    }
    
    fPDFData = NULL;

    this-make3DReady();
}

SampleWindow::~SampleWindow() {
    delete fPicture;
    delete fPdfCanvas;<commit_msg>fix typo:<commit_after>#include "SampleApp.h"

#include "SkData.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkGpuDevice.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkPaint.h"
#include "SkPicture.h"
#include "SkStream.h"
#include "SkTime.h"
#include "SkWindow.h"

#include "SampleCode.h"
#include "GrContext.h"
#include "SkTypeface.h"

#include "GrGLInterface.h"

#include "SkPDFDevice.h"
#include "SkPDFDocument.h"
#include "SkStream.h"

#define TEST_GPIPEx

#ifdef  TEST_GPIPE
#define PIPE_FILE
#define FILE_PATH "/path/to/drawing.data"
#endif

#define USE_ARROWS_FOR_ZOOM true
//#define DEFAULT_TO_GPU

extern SkView* create_overview(int, const SkViewFactory[]);

#define SK_SUPPORT_GL

#define ANIMATING_EVENTTYPE "nextSample"
#define ANIMATING_DELAY     750

#ifdef SK_DEBUG
    #define FPS_REPEAT_MULTIPLIER   1
#else
    #define FPS_REPEAT_MULTIPLIER   10
#endif
#define FPS_REPEAT_COUNT    (10 * FPS_REPEAT_MULTIPLIER)

#ifdef SK_SUPPORT_GL
    #include "GrGLConfig.h"
#endif

static SampleWindow* gSampleWindow;

///////////////
static const char view_inval_msg[] = "view-inval-msg";

void SampleWindow::postInvalDelay() {
    SkEvent* evt = new SkEvent(view_inval_msg);
    evt->post(this->getSinkID(), 1);
}

static bool isInvalEvent(const SkEvent& evt) {
    return evt.isType(view_inval_msg);
}
//////////////////

SkViewRegister* SkViewRegister::gHead;
SkViewRegister::SkViewRegister(SkViewFactory fact) : fFact(fact) {
    static bool gOnce;
    if (!gOnce) {
        gHead = NULL;
        gOnce = true;
    }

    fChain = gHead;
    gHead = this;
}

#if defined(SK_SUPPORT_GL)
    #define SK_USE_SHADERS
#endif

#if 0
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFURLAccess.h>

static void testpdf() {
    CFStringRef path = CFStringCreateWithCString(NULL, "/test.pdf",
                                                 kCFStringEncodingUTF8);
    CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path,
                                              kCFURLPOSIXPathStyle,
                                              false);
    CFRelease(path);
    CGRect box = CGRectMake(0, 0, 8*72, 10*72);
    CGContextRef cg = CGPDFContextCreateWithURL(url, &box, NULL);
    CFRelease(url);

    CGContextBeginPage(cg, &box);
    CGRect r = CGRectMake(10, 10, 40 + 0.5, 50 + 0.5);
    CGContextFillEllipseInRect(cg, r);
    CGContextEndPage(cg);
    CGContextRelease(cg);

    if (false) {
        SkBitmap bm;
        bm.setConfig(SkBitmap::kA8_Config, 64, 64);
        bm.allocPixels();
        bm.eraseColor(0);

        SkCanvas canvas(bm);

    }
}
#endif

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

enum FlipAxisEnum {
    kFlipAxis_X = (1 << 0),
    kFlipAxis_Y = (1 << 1)
};

static SkTriState cycle_tristate(SkTriState state) {
    static const SkTriState gCycle[] = {
        /* kFalse_SkTriState   -> */  kUnknown_SkTriState,
        /* kTrue_SkTriState    -> */  kFalse_SkTriState,
        /* kUnknown_SkTriState -> */  kTrue_SkTriState,
    };
    return gCycle[state];
}

#include "SkDrawFilter.h"

class FlagsDrawFilter : public SkDrawFilter {
public:
    FlagsDrawFilter(SkTriState lcd, SkTriState aa, SkTriState filter,
                    SkTriState hinting) :
        fLCDState(lcd), fAAState(aa), fFilterState(filter), fHintingState(hinting) {}

    virtual void filter(SkPaint* paint, Type t) {
        if (kText_Type == t && kUnknown_SkTriState != fLCDState) {
            paint->setLCDRenderText(kTrue_SkTriState == fLCDState);
        }
        if (kUnknown_SkTriState != fAAState) {
            paint->setAntiAlias(kTrue_SkTriState == fAAState);
        }
        if (kUnknown_SkTriState != fFilterState) {
            paint->setFilterBitmap(kTrue_SkTriState == fFilterState);
        }
        if (kUnknown_SkTriState != fHintingState) {
            paint->setHinting(kTrue_SkTriState == fHintingState ?
                              SkPaint::kNormal_Hinting :
                              SkPaint::kSlight_Hinting);
        }
    }

private:
    SkTriState  fLCDState;
    SkTriState  fAAState;
    SkTriState  fFilterState;
    SkTriState  fHintingState;
};

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

#define MAX_ZOOM_LEVEL  8
#define MIN_ZOOM_LEVEL  -8

static const char gCharEvtName[] = "SampleCode_Char_Event";
static const char gKeyEvtName[] = "SampleCode_Key_Event";
static const char gTitleEvtName[] = "SampleCode_Title_Event";
static const char gPrefSizeEvtName[] = "SampleCode_PrefSize_Event";
static const char gFastTextEvtName[] = "SampleCode_FastText_Event";

bool SampleCode::CharQ(const SkEvent& evt, SkUnichar* outUni) {
    if (evt.isType(gCharEvtName, sizeof(gCharEvtName) - 1)) {
        if (outUni) {
            *outUni = evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::KeyQ(const SkEvent& evt, SkKey* outKey) {
    if (evt.isType(gKeyEvtName, sizeof(gKeyEvtName) - 1)) {
        if (outKey) {
            *outKey = (SkKey)evt.getFast32();
        }
        return true;
    }
    return false;
}

bool SampleCode::TitleQ(const SkEvent& evt) {
    return evt.isType(gTitleEvtName, sizeof(gTitleEvtName) - 1);
}

void SampleCode::TitleR(SkEvent* evt, const char title[]) {
    SkASSERT(evt && TitleQ(*evt));
    evt->setString(gTitleEvtName, title);
}

bool SampleCode::PrefSizeQ(const SkEvent& evt) {
    return evt.isType(gPrefSizeEvtName, sizeof(gPrefSizeEvtName) - 1);
}

void SampleCode::PrefSizeR(SkEvent* evt, SkScalar width, SkScalar height) {
    SkASSERT(evt && PrefSizeQ(*evt));
    SkScalar size[2];
    size[0] = width;
    size[1] = height;
    evt->setScalars(gPrefSizeEvtName, 2, size);
}

bool SampleCode::FastTextQ(const SkEvent& evt) {
    return evt.isType(gFastTextEvtName, sizeof(gFastTextEvtName) - 1);
}

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

static SkMSec gAnimTime;
static SkMSec gAnimTimePrev;

SkMSec SampleCode::GetAnimTime() { return gAnimTime; }
SkMSec SampleCode::GetAnimTimeDelta() { return gAnimTime - gAnimTimePrev; }
SkScalar SampleCode::GetAnimSecondsDelta() {
    return SkDoubleToScalar(GetAnimTimeDelta() / 1000.0);
}

SkScalar SampleCode::GetAnimScalar(SkScalar speed, SkScalar period) {
    // since gAnimTime can be up to 32 bits, we can't convert it to a float
    // or we'll lose the low bits. Hence we use doubles for the intermediate
    // calculations
    double seconds = (double)gAnimTime / 1000.0;
    double value = SkScalarToDouble(speed) * seconds;
    if (period) {
        value = ::fmod(value, SkScalarToDouble(period));
    }
    return SkDoubleToScalar(value);
}

GrContext* SampleCode::GetGr() {
    return gSampleWindow ? gSampleWindow->getGrContext() : NULL;
}

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

static SkView* curr_view(SkWindow* wind) {
    SkView::F2BIter iter(wind);
    return iter.next();
}

void SampleWindow::setZoomCenter(float x, float y)
{
    fZoomCenterX = SkFloatToScalar(x);
    fZoomCenterY = SkFloatToScalar(y);
}

bool SampleWindow::setGrContext(GrContext* context)
{
    if (fGrContext) {
        fGrContext->unref();
    }
    fGrContext = context;
    fGrContext->ref();
    return true;
}

GrContext* SampleWindow::getGrContext()
{
    return fGrContext;
}

bool SampleWindow::zoomIn()
{
    // Arbitrarily decided
    if (fFatBitsScale == 25) return false;
    fFatBitsScale++;
    this->inval(NULL);
    return true;
}

bool SampleWindow::zoomOut()
{
    if (fFatBitsScale == 1) return false;
    fFatBitsScale--;
    this->inval(NULL);
    return true;
}

void SampleWindow::toggleZoomer()
{
    fShowZoomer = !fShowZoomer;
    this->inval(NULL);
}

void SampleWindow::updatePointer(int x, int y)
{
    fMouseX = x;
    fMouseY = y;
    if (fShowZoomer) {
        this->inval(NULL);
    }
}

bool SampleWindow::make3DReady() {

#if defined(SK_SUPPORT_GL)
    if (attachGL()) {
        if (NULL != fGrContext) {
        // various gr lifecycle tests
        #if   0
            fGrContext->freeGpuResources();
        #elif 0
            // this will leak resources.
            fGrContext->contextLost();
        #elif 0
            GrAssert(1 == fGrContext->refcnt());
            fGrContext->unref();
            fGrContext = NULL;
        #endif
        }

        if (NULL == fGrContext) {
        #if defined(SK_USE_SHADERS)
            fGrContext = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
        #else
            fGrContext = GrContext::Create(kOpenGL_Fixed_GrEngine, NULL);
        #endif
            SkDebugf("---- constructor\n");
        }

        if (NULL != fGrContext) {
            return true;
        } else {
            detachGL();
        }
    }
#endif
    SkDebugf("Failed to setup 3D");
    return false;
}

SampleWindow::CanvasType SampleWindow::cycle_canvastype(CanvasType ct) {
    static const CanvasType gCT[] = {
        kPicture_CanvasType,
        kGPU_CanvasType,
        kRaster_CanvasType
    };
    return gCT[ct];
}

SampleWindow::SampleWindow(void* hwnd, int argc, char** argv) : INHERITED(hwnd) {
    gSampleWindow = this;

#ifdef  PIPE_FILE
    //Clear existing file or create file if it doesn't exist
    FILE* f = fopen(FILE_PATH, "wb");
    fclose(f);
#endif
     
    fPicture = NULL;

    fGrContext = NULL;
    fGrRenderTarget = NULL;

#ifdef DEFAULT_TO_GPU
    fCanvasType = kGPU_CanvasType;
#else
    fCanvasType = kRaster_CanvasType;
#endif
    fUseClip = false;
    fNClip = false;
    fRepeatDrawing = false;
    fAnimating = false;
    fRotate = false;
    fScale = false;
    fRequestGrabImage = false;
    fUsePipe = false;
    fMeasureFPS = false;
    fLCDState = kUnknown_SkTriState;
    fAAState = kUnknown_SkTriState;
    fFilterState = kUnknown_SkTriState;
    fHintingState = kUnknown_SkTriState;
    fFlipAxis = 0;
    fScrollTestX = fScrollTestY = 0;

    fMouseX = fMouseY = 0;
    fFatBitsScale = 8;
    fTypeface = SkTypeface::CreateFromTypeface(NULL, SkTypeface::kBold);
    fShowZoomer = false;

    fZoomLevel = 0;
    fZoomScale = SK_Scalar1;

    fSaveToPdf = false;
    fPdfCanvas = NULL;

//    this->setConfig(SkBitmap::kRGB_565_Config);
    this->setConfig(SkBitmap::kARGB_8888_Config);
    this->setVisibleP(true);
    this->setClipToBounds(false);

    {
        const SkViewRegister* reg = SkViewRegister::Head();
        while (reg) {
            *fSamples.append() = reg->factory();
            reg = reg->next();
        }
    }
    fCurrIndex = 0;
    if (argc > 1) {
        int i, count = fSamples.count();
        for (i = 0; i < count; i++) {
            SkString title = getSampleTitle(i);
            if (title.equals(argv[1])) {
                fCurrIndex = i;
                break;
            }
        }
        if (i == count) {
            fprintf(stderr, "Unknown sample \"%s\"\n", argv[1]);
        }
    }
    this->loadView(fSamples[fCurrIndex]());

    // If another constructor set our dimensions, ensure that our
    // onSizeChange gets called.
    if (this->height() && this->width()) {
        this->onSizeChange();
    }
    
    fPDFData = NULL;

    this->make3DReady();
}

SampleWindow::~SampleWindow() {
    delete fPicture;
    delete fPdfCanvas;
{'fraction_non_alphanumeric': 0.14319280046105423, 'fraction_numerical': 0.008689098727667686, 'mean_word_length': 2.5513224181360203, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2453621', 'n_tokens_mistral': 7688, 'n_tokens_neox': 7508, 'n_words': 1542}