summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/skia/experimental/PdfViewer/src/SkPdfDiffEncoder.cpp
blob: 3ea0d37363a2e234a4390ebf51d5a6cef97687c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPdfDiffEncoder.h"
#include "SkPdfNativeTokenizer.h"

#ifdef PDF_TRACE_DIFF_IN_PNG
#include "SkBitmap.h"
#include "SkBitmapDevice.h"
#include "SkCanvas.h"
#include "SkClipStack.h"
#include "SkColor.h"
#include "SkImageEncoder.h"
#include "SkPaint.h"
#include "SkPath.h"
#include "SkRegion.h"
#include "SkScalar.h"
#include "SkString.h"

extern "C" SkBitmap* gDumpBitmap;
extern "C" SkCanvas* gDumpCanvas;
SkBitmap* gDumpBitmap = NULL;
SkCanvas* gDumpCanvas = NULL;
static int gReadOp;
static int gOpCounter;
static SkString gLastKeyword;
#endif  // PDF_TRACE_DIFF_IN_PNG

void SkPdfDiffEncoder::WriteToFile(PdfToken* token) {
#ifdef PDF_TRACE_DIFF_IN_PNG
    gReadOp++;
    gOpCounter++;

    // Only attempt to write if the dump bitmap and canvas are non NULL. They are set by
    // pdf_viewer_main.cpp
    if (NULL == gDumpBitmap || NULL == gDumpCanvas) {
        return;
    }

    // TODO(edisonn): this code is used to make a step by step history of all the draw operations
    // so we could find the step where something is wrong.
    if (!gLastKeyword.isEmpty()) {
        gDumpCanvas->flush();

        // Copy the existing drawing. Then we will draw the difference caused by this command,
        // highlighted with a blue border.
        SkBitmap bitmap;
        if (gDumpBitmap->copyTo(&bitmap, SkBitmap::kARGB_8888_Config)) {

            SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
            SkCanvas canvas(device);

            // draw context stuff here
            SkPaint blueBorder;
            blueBorder.setColor(SK_ColorBLUE);
            blueBorder.setStyle(SkPaint::kStroke_Style);
            blueBorder.setTextSize(SkDoubleToScalar(20));

            SkString str;

            const SkClipStack* clipStack = gDumpCanvas->getClipStack();
            if (clipStack) {
                SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
                const SkClipStack::Element* elem;
                double y = 0;
                int total = 0;
                while ((elem = iter.next()) != NULL) {
                    total++;
                    y += 30;

                    switch (elem->getType()) {
                        case SkClipStack::Element::kRect_Type:
                            canvas.drawRect(elem->getRect(), blueBorder);
                            canvas.drawText("Rect Clip", strlen("Rect Clip"),
                                            SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
                            break;
                        case SkClipStack::Element::kPath_Type:
                            canvas.drawPath(elem->getPath(), blueBorder);
                            canvas.drawText("Path Clip", strlen("Path Clip"),
                                            SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
                            break;
                        case SkClipStack::Element::kEmpty_Type:
                            canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!"),
                                            SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
                            break;
                        default:
                            canvas.drawText("Unknown Clip!!!", strlen("Unknown Clip!!!"),
                                            SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
                            break;
                    }
                }

                y += 30;
                str.printf("Number of clips in stack: %i", total);
                canvas.drawText(str.c_str(), str.size(),
                                SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
            }

            const SkRegion& clipRegion = gDumpCanvas->getTotalClip();
            SkPath clipPath;
            if (clipRegion.getBoundaryPath(&clipPath)) {
                SkPaint redBorder;
                redBorder.setColor(SK_ColorRED);
                redBorder.setStyle(SkPaint::kStroke_Style);
                canvas.drawPath(clipPath, redBorder);
            }

            canvas.flush();

            SkString out;

            // TODO(edisonn): overlay on top of image inf about the clip , grafic state, the stack

            out.appendf("/tmp/log_step_by_step/step-%i-%s.png", gOpCounter, gLastKeyword.c_str());

            SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
        }
    }

    if (token->fType == kKeyword_TokenType && token->fKeyword && token->fKeywordLength > 0) {
        gLastKeyword.set(token->fKeyword, token->fKeywordLength);
    } else {
        gLastKeyword.reset();
    }
#endif
}