Home | History | Annotate | Download | only in urlhandlers
      1 /*
      2  * Copyright 2016 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 "UrlHandler.h"
      9 
     10 #include "microhttpd.h"
     11 #include "../Request.h"
     12 #include "../Response.h"
     13 
     14 using namespace Response;
     15 
     16 bool BreakHandler::canHandle(const char* method, const char* url) {
     17     static const char* kBasePath = "/break";
     18     return 0 == strcmp(method, MHD_HTTP_METHOD_GET) &&
     19            0 == strncmp(url, kBasePath, strlen(kBasePath));
     20 }
     21 
     22 SkColor BreakHandler::GetPixel(Request* request, int x, int y) {
     23     SkCanvas* canvas = request->getCanvas();
     24     canvas->flush();
     25     SkAutoTDelete<SkBitmap> bitmap(request->getBitmapFromCanvas(canvas));
     26     SkASSERT(bitmap);
     27     bitmap->lockPixels();
     28     uint8_t* start = ((uint8_t*) bitmap->getPixels()) + (y * Request::kImageWidth + x) * 4;
     29     SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
     30     bitmap->unlockPixels();
     31     return result;
     32 }
     33 
     34 
     35 int BreakHandler::handle(Request* request, MHD_Connection* connection,
     36                          const char* url, const char* method,
     37                          const char* upload_data, size_t* upload_data_size) {
     38     SkTArray<SkString> commands;
     39     SkStrSplit(url, "/", &commands);
     40 
     41     if (!request->fPicture.get() || commands.count() != 4) {
     42         return MHD_NO;
     43     }
     44 
     45     // /break/<n>/<x>/<y>
     46     int n;
     47     sscanf(commands[1].c_str(), "%d", &n);
     48     int x;
     49     sscanf(commands[2].c_str(), "%d", &x);
     50     int y;
     51     sscanf(commands[3].c_str(), "%d", &y);
     52 
     53     int count = request->fDebugCanvas->getSize();
     54     SkASSERT(n < count);
     55 
     56     SkCanvas* canvas = request->getCanvas();
     57     canvas->clear(SK_ColorWHITE);
     58     int saveCount = canvas->save();
     59     for (int i = 0; i <= n; ++i) {
     60         request->fDebugCanvas->getDrawCommandAt(i)->execute(canvas);
     61     }
     62     SkColor target = GetPixel(request, x, y);
     63     Json::Value response(Json::objectValue);
     64     Json::Value startColor(Json::arrayValue);
     65     startColor.append(Json::Value(SkColorGetR(target)));
     66     startColor.append(Json::Value(SkColorGetG(target)));
     67     startColor.append(Json::Value(SkColorGetB(target)));
     68     startColor.append(Json::Value(SkColorGetA(target)));
     69     response["startColor"] = startColor;
     70     response["endColor"] = startColor;
     71     response["endOp"] = Json::Value(n);
     72     for (int i = n + 1; i < n + count; ++i) {
     73         int index = i % count;
     74         if (index == 0) {
     75             // reset canvas for wraparound
     76             canvas->restoreToCount(saveCount);
     77             canvas->clear(SK_ColorWHITE);
     78             saveCount = canvas->save();
     79         }
     80         request->fDebugCanvas->getDrawCommandAt(index)->execute(canvas);
     81         SkColor current = GetPixel(request, x, y);
     82         if (current != target) {
     83             Json::Value endColor(Json::arrayValue);
     84             endColor.append(Json::Value(SkColorGetR(current)));
     85             endColor.append(Json::Value(SkColorGetG(current)));
     86             endColor.append(Json::Value(SkColorGetB(current)));
     87             endColor.append(Json::Value(SkColorGetA(current)));
     88             response["endColor"] = endColor;
     89             response["endOp"] = Json::Value(index);
     90             break;
     91         }
     92     }
     93     canvas->restoreToCount(saveCount);
     94     SkDynamicMemoryWStream stream;
     95     stream.writeText(Json::FastWriter().write(response).c_str());
     96     SkAutoTUnref<SkData> data(stream.copyToData());
     97     return SendData(connection, data, "application/json");
     98 }
     99 
    100