Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkPdfDiffEncoder.h"
      9 #include "SkPdfNativeTokenizer.h"
     10 
     11 #ifdef PDF_TRACE_DIFF_IN_PNG
     12 #include "SkBitmap.h"
     13 #include "SkBitmapDevice.h"
     14 #include "SkCanvas.h"
     15 #include "SkClipStack.h"
     16 #include "SkColor.h"
     17 #include "SkImageEncoder.h"
     18 #include "SkPaint.h"
     19 #include "SkPath.h"
     20 #include "SkRegion.h"
     21 #include "SkScalar.h"
     22 #include "SkString.h"
     23 
     24 extern "C" SkBitmap* gDumpBitmap;
     25 extern "C" SkCanvas* gDumpCanvas;
     26 SkBitmap* gDumpBitmap = NULL;
     27 SkCanvas* gDumpCanvas = NULL;
     28 static int gReadOp;
     29 static int gOpCounter;
     30 static SkString gLastKeyword;
     31 #endif  // PDF_TRACE_DIFF_IN_PNG
     32 
     33 void SkPdfDiffEncoder::WriteToFile(PdfToken* token) {
     34 #ifdef PDF_TRACE_DIFF_IN_PNG
     35     gReadOp++;
     36     gOpCounter++;
     37 
     38     // Only attempt to write if the dump bitmap and canvas are non NULL. They are set by
     39     // pdf_viewer_main.cpp
     40     if (NULL == gDumpBitmap || NULL == gDumpCanvas) {
     41         return;
     42     }
     43 
     44     // TODO(edisonn): this code is used to make a step by step history of all the draw operations
     45     // so we could find the step where something is wrong.
     46     if (!gLastKeyword.isEmpty()) {
     47         gDumpCanvas->flush();
     48 
     49         // Copy the existing drawing. Then we will draw the difference caused by this command,
     50         // highlighted with a blue border.
     51         SkBitmap bitmap;
     52         if (gDumpBitmap->copyTo(&bitmap, SkBitmap::kARGB_8888_Config)) {
     53 
     54             SkAutoTUnref<SkBaseDevice> device(SkNEW_ARGS(SkBitmapDevice, (bitmap)));
     55             SkCanvas canvas(device);
     56 
     57             // draw context stuff here
     58             SkPaint blueBorder;
     59             blueBorder.setColor(SK_ColorBLUE);
     60             blueBorder.setStyle(SkPaint::kStroke_Style);
     61             blueBorder.setTextSize(SkDoubleToScalar(20));
     62 
     63             SkString str;
     64 
     65             const SkClipStack* clipStack = gDumpCanvas->getClipStack();
     66             if (clipStack) {
     67                 SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
     68                 const SkClipStack::Element* elem;
     69                 double y = 0;
     70                 int total = 0;
     71                 while ((elem = iter.next()) != NULL) {
     72                     total++;
     73                     y += 30;
     74 
     75                     switch (elem->getType()) {
     76                         case SkClipStack::Element::kRect_Type:
     77                             canvas.drawRect(elem->getRect(), blueBorder);
     78                             canvas.drawText("Rect Clip", strlen("Rect Clip"),
     79                                             SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
     80                             break;
     81                         case SkClipStack::Element::kPath_Type:
     82                             canvas.drawPath(elem->getPath(), blueBorder);
     83                             canvas.drawText("Path Clip", strlen("Path Clip"),
     84                                             SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
     85                             break;
     86                         case SkClipStack::Element::kEmpty_Type:
     87                             canvas.drawText("Empty Clip!!!", strlen("Empty Clip!!!"),
     88                                             SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
     89                             break;
     90                         default:
     91                             canvas.drawText("Unknown Clip!!!", strlen("Unknown Clip!!!"),
     92                                             SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
     93                             break;
     94                     }
     95                 }
     96 
     97                 y += 30;
     98                 str.printf("Number of clips in stack: %i", total);
     99                 canvas.drawText(str.c_str(), str.size(),
    100                                 SkDoubleToScalar(10), SkDoubleToScalar(y), blueBorder);
    101             }
    102 
    103             const SkRegion& clipRegion = gDumpCanvas->getTotalClip();
    104             SkPath clipPath;
    105             if (clipRegion.getBoundaryPath(&clipPath)) {
    106                 SkPaint redBorder;
    107                 redBorder.setColor(SK_ColorRED);
    108                 redBorder.setStyle(SkPaint::kStroke_Style);
    109                 canvas.drawPath(clipPath, redBorder);
    110             }
    111 
    112             canvas.flush();
    113 
    114             SkString out;
    115 
    116             // TODO(edisonn): overlay on top of image inf about the clip , grafic state, the stack
    117 
    118             out.appendf("/tmp/log_step_by_step/step-%i-%s.png", gOpCounter, gLastKeyword.c_str());
    119 
    120             SkImageEncoder::EncodeFile(out.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
    121         }
    122     }
    123 
    124     if (token->fType == kKeyword_TokenType && token->fKeyword && token->fKeywordLength > 0) {
    125         gLastKeyword.set(token->fKeyword, token->fKeywordLength);
    126     } else {
    127         gLastKeyword.reset();
    128     }
    129 #endif
    130 }
    131