1f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SampleCode.h"
2f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkView.h"
3f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCanvas.h"
4f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkGPipe.h"
5f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkSockets.h"
6f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkNetPipeController.h"
7f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkCornerPathEffect.h"
8f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkColorPalette.h"
9f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#include "SkOSMenu.h"
10f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
11ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
12ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com/**
13ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Drawing Client
14ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com *
15d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * A drawing client that allows a user to perform simple brush stokes with
16d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * a selected color and brush size. The drawing client communicates with a
17ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * drawing server to send/receive data to/from other clients connected to the
18ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * same server. The drawing client stores data in fData and fBuffer depending on
19ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * the data type. Append type means that the drawing data is a completed stroke
20d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * and Replace type means that the drawing data is in progress and will be
21d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * replaced by subsequent data. fData and fBuffer are read by a pipe reader and
22ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * reproduce the drawing. When the client is in a normal state, the data stored
23ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * on the client and the server should be identical.
24ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * The drawing client is also able to switch between vector and bitmap drawing.
25ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * The drawing client also renders the latest drawing stroke locally in order to
26d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * produce better reponses. This can be disabled by calling
27d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * controller.disablePlayBack(), which will introduce a lag between the input
28ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * and the drawing.
29ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * Note: in order to keep up with the drawing data, the client will try to read
30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com * a few times each frame in case more than one frame worth of data has been
31ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * received and render them together. This behavior can be adjusted by tweaking
32ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com * MAX_READ_PER_FRAME or disabled by turning fSync to false
33ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com */
34ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
35f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com#define MAX_READ_PER_FRAME 5
36ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com
37f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comclass DrawingClientView : public SampleView {
38f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.compublic:
39d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    DrawingClientView() {
40f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fSocket = NULL;
41f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = 0;
42f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPalette = new SkColorPalette;
43f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPalette->setSize(100, 300);
44f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPalette->setVisibleP(true);
45f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->attachChildToFront(fPalette);
46f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPalette->unref();
474b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org        fBrushSize = 2.5;
48f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fAA = false;
49f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPaletteVisible = true;
50ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        fSync = true;
51ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        fVector = true;
52f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
53f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    ~DrawingClientView() {
54f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fSocket) {
55f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            delete fSocket;
56f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
57f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fData.reset();
58f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBuffer.reset();
59f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
61f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void requestMenu(SkOSMenu* menu) {
62f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->setTitle("Drawing Client");
63d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        menu->appendTextField("Server IP", "Server IP", this->getSinkID(),
64ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                              "IP address or hostname");
65f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendSwitch("Vector", "Vector", this->getSinkID(), fVector);
66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        menu->appendSlider("Brush Size", "Brush Size", this->getSinkID(), 1.0,
67ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                           100.0, fBrushSize);
68f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendSwitch("Anti-Aliasing", "AA", this->getSinkID(), fAA);
69d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        menu->appendSwitch("Show Color Palette", "Palette", this->getSinkID(),
70ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                           fPaletteVisible);
71f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendSwitch("Sync", "Sync", this->getSinkID(), fSync);
72f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        menu->appendAction("Clear", this->getSinkID());
73f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
75f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprotected:
76d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
77f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    static void readData(int cid, const void* data, size_t size,
78f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                         SkSocket::DataType type, void* context) {
79f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        DrawingClientView* view = (DrawingClientView*)context;
80f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        view->onRead(cid, data, size, type);
81f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
83f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void onRead(int cid, const void* data, size_t size, SkSocket::DataType type) {
84f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (size > 0) {
85f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fBuffer.reset();
86f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            if (type == SkSocket::kPipeReplace_type)
87f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fBuffer.append(size, (const char*)data);
88f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            else if (type == SkSocket::kPipeAppend_type)
89f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fData.append(size, (const char*)data);
90f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            else {
91f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                //other types of data
92f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            }
93f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
94f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
95d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
96f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool onQuery(SkEvent* evt) {
97f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (SampleCode::TitleQ(*evt)) {
98f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SampleCode::TitleR(evt, "Drawing Client");
99f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
100f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
101d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
102f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return this->INHERITED::onQuery(evt);
103f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
104d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
105f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool onEvent(const SkEvent& evt) {;
106ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindSliderValue(evt, "Brush Size", &fBrushSize))
107f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
108d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
109f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkString s;
110ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindText(evt, "Server IP", &s)) {
111f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            if (NULL != fSocket) {
112f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                delete fSocket;
113f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            }
114f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fSocket = new SkTCPClient(s.c_str(), 40000);
115f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fSocket->connectToServer();
116f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fSocket->suspendWrite();
117f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkDebugf("Connecting to %s\n", s.c_str());
118f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fData.reset();
119f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fBuffer.reset();
120f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            this->inval(NULL);
121f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
122f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
123ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindSwitchState(evt, "AA", &fAA) ||
124ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            SkOSMenu::FindSwitchState(evt, "Sync", &fSync))
125f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
126ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindSwitchState(evt, "Vector", &fVector)) {
127f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            this->clearBitmap();
128f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
129f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
130ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindAction(evt, "Clear")) {
131f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            this->clear();
132f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
133f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
134ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        if (SkOSMenu::FindSwitchState(evt, "Palette", &fPaletteVisible)) {
135f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fPalette->setVisibleP(fPaletteVisible);
136f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            return true;
137f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
138f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return this->INHERITED::onEvent(evt);
139f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
140d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
141f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
142f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return new Click(this);
143f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
144d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
145f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual bool onClick(SkView::Click* click) {
146f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        switch (click->fState) {
147f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            case SkView::Click::kDown_State:
148f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fCurrLine.moveTo(click->fCurr);
149f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fType = SkSocket::kPipeReplace_type;
150f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                if (fSocket)
151f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    fSocket->resumeWrite();
152f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                break;
153f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            case SkView::Click::kMoved_State:
154f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fCurrLine.lineTo(click->fCurr);
155f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                break;
156f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            case SkView::Click::kUp_State:
157f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fType = SkSocket::kPipeAppend_type;
158f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                break;
159f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            default:
160f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                break;
161f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
162f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        return true;
163f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
164d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
165f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void onDrawContent(SkCanvas* canvas) {
166f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fSocket) {
167f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            if (fSocket->isConnected()) {
168f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                if (fSync) {
169f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    int count = 0;
170f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    while (fSocket->readPacket(readData, this) > 0 &&
171d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                           count < MAX_READ_PER_FRAME)
172f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                        ++count;
173f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                }
174d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                else
175f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                    fSocket->readPacket(readData, this);
176f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            }
177d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            else
178f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                fSocket->connectToServer();
179f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
180f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        size_t bytesRead = 0;
181ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com        SkGPipeReader::Status status;
182f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkCanvas bufferCanvas(fBase);
183f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkCanvas* tempCanvas;
184f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        while (fTotalBytesRead < fData.count()) {
185f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            if (fVector)
186f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                tempCanvas = canvas;
187f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            else
188f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                tempCanvas = &bufferCanvas;
189d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            SkGPipeReader reader(tempCanvas);
190ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            status = reader.playback(fData.begin() + fTotalBytesRead,
191ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                     fData.count() - fTotalBytesRead,
192ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                     &bytesRead);
193f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkASSERT(SkGPipeReader::kError_Status != status);
194f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesRead += bytesRead;
195f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
196f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fVector)
197f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fTotalBytesRead = 0;
198f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        else
199f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            canvas->drawBitmap(fBase, 0, 0, NULL);
200d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
201f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        size_t totalBytesRead = 0;
202f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        while (totalBytesRead < fBuffer.count()) {
203f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            SkGPipeReader reader(canvas);
204d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com            status = reader.playback(fBuffer.begin() + totalBytesRead,
205d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                                     fBuffer.count() - totalBytesRead,
206ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com                                     &bytesRead);
207ef7bdfac618f60e9edc9f42cd4661d563937e6d8yangsu@google.com            SkASSERT(SkGPipeReader::kError_Status != status);
208f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            totalBytesRead += bytesRead;
209f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
210d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
211f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkNetPipeController controller(canvas);
212f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkGPipeWriter writer;
213d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        SkCanvas* writerCanvas = writer.startRecording(&controller,
214f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com                                                       SkGPipeWriter::kCrossProcess_Flag);
215d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
216f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        //controller.disablePlayback();
217f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        SkPaint p;
218f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setColor(fPalette->getColor());
219f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setStyle(SkPaint::kStroke_Style);
220f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setStrokeWidth(fBrushSize);
221f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setStrokeCap(SkPaint::kRound_Cap);
222f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setStrokeJoin(SkPaint::kRound_Join);
223f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setAntiAlias(fAA);
224f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        p.setPathEffect(new SkCornerPathEffect(55))->unref();
225f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        writerCanvas->drawPath(fCurrLine, p);
226f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        writer.endRecording();
227d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
228f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        controller.writeToSocket(fSocket, fType);
229f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        if (fType == SkSocket::kPipeAppend_type && fSocket) {
230f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fSocket->suspendWrite();
231f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com            fCurrLine.reset();
232f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        }
233d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
234f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->inval(NULL);
235f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
236d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
237f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    virtual void onSizeChange() {
238f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->INHERITED::onSizeChange();
239f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fPalette->setLoc(this->width()-100, 0);
240f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBase.setConfig(SkBitmap::kARGB_8888_Config, this->width(), this->height());
241f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBase.allocPixels(NULL);
242f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->clearBitmap();
243f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
244d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
245f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comprivate:
246f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void clear() {
247f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fData.reset();
248f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBuffer.reset();
249f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fCurrLine.reset();
250f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = 0;
251f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        this->clearBitmap();
252f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
253f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    void clearBitmap() {
254f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fTotalBytesRead = 0;
255f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com        fBase.eraseColor(fBGColor);
256f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    }
257f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTDArray<char>     fData;
258f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTDArray<char>     fBuffer;
259f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkBitmap            fBase;
260f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkPath              fCurrLine;
261f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkTCPClient*        fSocket;
262f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkSocket::DataType  fType;
263f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkColorPalette*     fPalette;
264f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool                fPaletteVisible;
265f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    size_t              fTotalBytesRead;
266f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    SkScalar            fBrushSize;
267f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool                fAA;
268f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool                fSync;
269f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    bool                fVector;
270d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
271f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com    typedef SampleView INHERITED;
272f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com};
273f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
274f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
275f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com///////////////////////////////////////////////////////////////////////////////
276f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.com
277f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkView* MyFactory() { return new DrawingClientView; }
278f3493f0e1f92a8a284adb93ecbf350401e1c7423yangsu@google.comstatic SkViewRegister reg(MyFactory);
279