Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
2 /*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
10 #include "SkColorPriv.h"
11 #include "SkDebugCanvas.h"
12 #include "SkDrawCommand.h"
13 #include "SkDrawFilter.h"
14 #include "SkDevice.h"
15 #include "SkXfermode.h"
17 SkDebugCanvas::SkDebugCanvas(int width, int height)
18 : INHERITED(width, height)
19 , fWidth(width)
20 , fHeight(height)
21 , fFilter(false)
22 , fMegaVizMode(false)
23 , fIndex(0)
24 , fOverdrawViz(false)
25 , fOverdrawFilter(NULL)
26 , fOverrideTexFiltering(false)
27 , fTexOverrideFilter(NULL)
28 , fOutstandingSaveCount(0) {
29 fUserMatrix.reset();
31 // SkPicturePlayback uses the base-class' quickReject calls to cull clipped
32 // operations. This can lead to problems in the debugger which expects all
33 // the operations in the captured skp to appear in the debug canvas. To
34 // circumvent this we create a wide open clip here (an empty clip rect
35 // is not sufficient).
36 // Internally, the SkRect passed to clipRect is converted to an SkIRect and
37 // rounded out. The following code creates a nearly maximal rect that will
38 // not get collapsed by the coming conversions (Due to precision loss the
39 // inset has to be surprisingly large).
40 SkIRect largeIRect = SkIRect::MakeLargest();
41 largeIRect.inset(1024, 1024);
42 SkRect large = SkRect::Make(largeIRect);
43 #ifdef SK_DEBUG
44 large.roundOut(&largeIRect);
45 SkASSERT(!largeIRect.isEmpty());
46 #endif
47 // call the base class' version to avoid adding a draw command
48 this->INHERITED::onClipRect(large, SkRegion::kReplace_Op, kHard_ClipEdgeStyle);
49 }
51 SkDebugCanvas::~SkDebugCanvas() {
52 fCommandVector.deleteAll();
53 SkSafeUnref(fOverdrawFilter);
54 SkSafeUnref(fTexOverrideFilter);
55 }
57 void SkDebugCanvas::addDrawCommand(SkDrawCommand* command) {
58 fCommandVector.push(command);
59 }
61 void SkDebugCanvas::draw(SkCanvas* canvas) {
62 if (!fCommandVector.isEmpty()) {
63 drawTo(canvas, fCommandVector.count() - 1);
64 }
65 }
67 void SkDebugCanvas::applyUserTransform(SkCanvas* canvas) {
68 canvas->concat(fUserMatrix);
69 }
71 int SkDebugCanvas::getCommandAtPoint(int x, int y, int index) {
72 SkBitmap bitmap;
73 bitmap.allocPixels(SkImageInfo::MakeN32Premul(1, 1));
75 SkCanvas canvas(bitmap);
76 canvas.translate(SkIntToScalar(-x), SkIntToScalar(-y));
77 applyUserTransform(&canvas);
79 int layer = 0;
80 SkColor prev = bitmap.getColor(0,0);
81 for (int i = 0; i < index; i++) {
82 if (fCommandVector[i]->isVisible()) {
83 fCommandVector[i]->execute(&canvas);
84 }
85 if (prev != bitmap.getColor(0,0)) {
86 layer = i;
87 }
88 prev = bitmap.getColor(0,0);
89 }
90 return layer;
91 }
93 static SkPMColor OverdrawXferModeProc(SkPMColor src, SkPMColor dst) {
94 // This table encodes the color progression of the overdraw visualization
95 static const SkPMColor gTable[] = {
96 SkPackARGB32(0x00, 0x00, 0x00, 0x00),
97 SkPackARGB32(0xFF, 128, 158, 255),
98 SkPackARGB32(0xFF, 170, 185, 212),
99 SkPackARGB32(0xFF, 213, 195, 170),
100 SkPackARGB32(0xFF, 255, 192, 127),
101 SkPackARGB32(0xFF, 255, 185, 85),
102 SkPackARGB32(0xFF, 255, 165, 42),
103 SkPackARGB32(0xFF, 255, 135, 0),
104 SkPackARGB32(0xFF, 255, 95, 0),
105 SkPackARGB32(0xFF, 255, 50, 0),
106 SkPackARGB32(0xFF, 255, 0, 0)
107 };
109 for (size_t i = 0; i < SK_ARRAY_COUNT(gTable)-1; ++i) {
110 if (gTable[i] == dst) {
111 return gTable[i+1];
112 }
113 }
115 return gTable[SK_ARRAY_COUNT(gTable)-1];
116 }
118 // The OverdrawFilter modifies every paint to use an SkProcXfermode which
119 // in turn invokes OverdrawXferModeProc
120 class SkOverdrawFilter : public SkDrawFilter {
121 public:
122 SkOverdrawFilter() {
123 fXferMode = SkProcXfermode::Create(OverdrawXferModeProc);
124 }
126 virtual ~SkOverdrawFilter() {
127 delete fXferMode;
128 }
130 virtual bool filter(SkPaint* p, Type) SK_OVERRIDE {
131 p->setXfermode(fXferMode);
132 return true;
133 }
135 protected:
136 SkXfermode* fXferMode;
138 private:
139 typedef SkDrawFilter INHERITED;
140 };
142 // SkTexOverrideFilter modifies every paint to use the specified
143 // texture filtering mode
144 class SkTexOverrideFilter : public SkDrawFilter {
145 public:
146 SkTexOverrideFilter() : fFilterLevel(SkPaint::kNone_FilterLevel) {
147 }
149 void setFilterLevel(SkPaint::FilterLevel filterLevel) {
150 fFilterLevel = filterLevel;
151 }
153 virtual bool filter(SkPaint* p, Type) SK_OVERRIDE {
154 p->setFilterLevel(fFilterLevel);
155 return true;
156 }
158 protected:
159 SkPaint::FilterLevel fFilterLevel;
161 private:
162 typedef SkDrawFilter INHERITED;
163 };
165 class SkDebugClipVisitor : public SkCanvas::ClipVisitor {
166 public:
167 SkDebugClipVisitor(SkCanvas* canvas) : fCanvas(canvas) {}
169 virtual void clipRect(const SkRect& r, SkRegion::Op, bool doAA) SK_OVERRIDE {
170 SkPaint p;
171 p.setColor(SK_ColorRED);
172 p.setStyle(SkPaint::kStroke_Style);
173 p.setAntiAlias(doAA);
174 fCanvas->drawRect(r, p);
175 }
176 virtual void clipRRect(const SkRRect& rr, SkRegion::Op, bool doAA) SK_OVERRIDE {
177 SkPaint p;
178 p.setColor(SK_ColorGREEN);
179 p.setStyle(SkPaint::kStroke_Style);
180 p.setAntiAlias(doAA);
181 fCanvas->drawRRect(rr, p);
182 }
183 virtual void clipPath(const SkPath& path, SkRegion::Op, bool doAA) SK_OVERRIDE {
184 SkPaint p;
185 p.setColor(SK_ColorBLUE);
186 p.setStyle(SkPaint::kStroke_Style);
187 p.setAntiAlias(doAA);
188 fCanvas->drawPath(path, p);
189 }
191 protected:
192 SkCanvas* fCanvas;
194 private:
195 typedef SkCanvas::ClipVisitor INHERITED;
196 };
198 // set up the saveLayer commands so that the active ones
199 // return true in their 'active' method
200 void SkDebugCanvas::markActiveCommands(int index) {
201 fActiveLayers.rewind();
202 fActiveCulls.rewind();
204 for (int i = 0; i < fCommandVector.count(); ++i) {
205 fCommandVector[i]->setActive(false);
206 }
208 for (int i = 0; i < index; ++i) {
209 SkDrawCommand::Action result = fCommandVector[i]->action();
210 if (SkDrawCommand::kPushLayer_Action == result) {
211 fActiveLayers.push(fCommandVector[i]);
212 } else if (SkDrawCommand::kPopLayer_Action == result) {
213 fActiveLayers.pop();
214 } else if (SkDrawCommand::kPushCull_Action == result) {
215 fActiveCulls.push(fCommandVector[i]);
216 } else if (SkDrawCommand::kPopCull_Action == result) {
217 fActiveCulls.pop();
218 }
219 }
221 for (int i = 0; i < fActiveLayers.count(); ++i) {
222 fActiveLayers[i]->setActive(true);
223 }
225 for (int i = 0; i < fActiveCulls.count(); ++i) {
226 fActiveCulls[i]->setActive(true);
227 }
228 }
230 void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
231 SkASSERT(!fCommandVector.isEmpty());
232 SkASSERT(index < fCommandVector.count());
233 int i = 0;
235 // This only works assuming the canvas and device are the same ones that
236 // were previously drawn into because they need to preserve all saves
237 // and restores.
238 // The visibility filter also requires a full re-draw - otherwise we can
239 // end up drawing the filter repeatedly.
240 if (fIndex < index && !fFilter && !fMegaVizMode) {
241 i = fIndex + 1;
242 } else {
243 for (int j = 0; j < fOutstandingSaveCount; j++) {
244 canvas->restore();
245 }
246 canvas->clear(SK_ColorTRANSPARENT);
247 canvas->resetMatrix();
248 SkRect rect = SkRect::MakeWH(SkIntToScalar(fWidth),
249 SkIntToScalar(fHeight));
250 canvas->clipRect(rect, SkRegion::kReplace_Op );
251 applyUserTransform(canvas);
252 fOutstandingSaveCount = 0;
253 }
255 // The setting of the draw filter has to go here (rather than in
256 // SkRasterWidget) due to the canvas restores this class performs.
257 // Since the draw filter is stored in the layer stack if we
258 // call setDrawFilter on anything but the root layer odd things happen.
259 if (fOverdrawViz) {
260 if (NULL == fOverdrawFilter) {
261 fOverdrawFilter = new SkOverdrawFilter;
262 }
264 if (fOverdrawFilter != canvas->getDrawFilter()) {
265 canvas->setDrawFilter(fOverdrawFilter);
266 }
267 } else if (fOverrideTexFiltering) {
268 if (NULL == fTexOverrideFilter) {
269 fTexOverrideFilter = new SkTexOverrideFilter;
270 }
272 if (fTexOverrideFilter != canvas->getDrawFilter()) {
273 canvas->setDrawFilter(fTexOverrideFilter);
274 }
275 } else {
276 canvas->setDrawFilter(NULL);
277 }
279 if (fMegaVizMode) {
280 this->markActiveCommands(index);
281 }
283 for (; i <= index; i++) {
284 if (i == index && fFilter) {
285 SkPaint p;
286 p.setColor(0xAAFFFFFF);
287 canvas->save();
288 canvas->resetMatrix();
289 SkRect mask;
290 mask.set(SkIntToScalar(0), SkIntToScalar(0),
291 SkIntToScalar(fWidth), SkIntToScalar(fHeight));
292 canvas->clipRect(mask, SkRegion::kReplace_Op, false);
293 canvas->drawRectCoords(SkIntToScalar(0), SkIntToScalar(0),
294 SkIntToScalar(fWidth), SkIntToScalar(fHeight), p);
295 canvas->restore();
296 }
298 if (fCommandVector[i]->isVisible()) {
299 if (fMegaVizMode && fCommandVector[i]->active()) {
300 // "active" commands execute their visualization behaviors:
301 // All active saveLayers get replaced with saves so all draws go to the
302 // visible canvas.
303 // All active culls draw their cull box
304 fCommandVector[i]->vizExecute(canvas);
305 } else {
306 fCommandVector[i]->execute(canvas);
307 }
309 fCommandVector[i]->trackSaveState(&fOutstandingSaveCount);
310 }
311 }
313 if (fMegaVizMode) {
314 SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
315 r.outset(SK_Scalar1, SK_Scalar1);
317 canvas->save();
318 // nuke the CTM
319 canvas->setMatrix(SkMatrix::I());
320 // turn off clipping
321 canvas->clipRect(r, SkRegion::kReplace_Op);
323 // visualize existing clips
324 SkDebugClipVisitor visitor(canvas);
326 canvas->replayClips(&visitor);
328 canvas->restore();
329 }
330 fMatrix = canvas->getTotalMatrix();
331 if (!canvas->getClipDeviceBounds(&fClip)) {
332 fClip.setEmpty();
333 }
334 fIndex = index;
335 }
337 void SkDebugCanvas::deleteDrawCommandAt(int index) {
338 SkASSERT(index < fCommandVector.count());
339 delete fCommandVector[index];
340 fCommandVector.remove(index);
341 }
343 SkDrawCommand* SkDebugCanvas::getDrawCommandAt(int index) {
344 SkASSERT(index < fCommandVector.count());
345 return fCommandVector[index];
346 }
348 void SkDebugCanvas::setDrawCommandAt(int index, SkDrawCommand* command) {
349 SkASSERT(index < fCommandVector.count());
350 delete fCommandVector[index];
351 fCommandVector[index] = command;
352 }
354 SkTDArray<SkString*>* SkDebugCanvas::getCommandInfo(int index) {
355 SkASSERT(index < fCommandVector.count());
356 return fCommandVector[index]->Info();
357 }
359 bool SkDebugCanvas::getDrawCommandVisibilityAt(int index) {
360 SkASSERT(index < fCommandVector.count());
361 return fCommandVector[index]->isVisible();
362 }
364 const SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() const {
365 return fCommandVector;
366 }
368 SkTDArray <SkDrawCommand*>& SkDebugCanvas::getDrawCommands() {
369 return fCommandVector;
370 }
372 // TODO(chudy): Free command string memory.
373 SkTArray<SkString>* SkDebugCanvas::getDrawCommandsAsStrings() const {
374 SkTArray<SkString>* commandString = new SkTArray<SkString>(fCommandVector.count());
375 if (!fCommandVector.isEmpty()) {
376 for (int i = 0; i < fCommandVector.count(); i ++) {
377 commandString->push_back() = fCommandVector[i]->toString();
378 }
379 }
380 return commandString;
381 }
383 void SkDebugCanvas::overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level) {
384 if (NULL == fTexOverrideFilter) {
385 fTexOverrideFilter = new SkTexOverrideFilter;
386 }
388 fOverrideTexFiltering = overrideTexFiltering;
389 fTexOverrideFilter->setFilterLevel(level);
390 }
392 void SkDebugCanvas::clear(SkColor color) {
393 addDrawCommand(new SkClearCommand(color));
394 }
396 void SkDebugCanvas::onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
397 this->addDrawCommand(new SkClipPathCommand(path, op, kSoft_ClipEdgeStyle == edgeStyle));
398 }
400 void SkDebugCanvas::onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
401 this->addDrawCommand(new SkClipRectCommand(rect, op, kSoft_ClipEdgeStyle == edgeStyle));
402 }
404 void SkDebugCanvas::onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) {
405 this->addDrawCommand(new SkClipRRectCommand(rrect, op, kSoft_ClipEdgeStyle == edgeStyle));
406 }
408 void SkDebugCanvas::onClipRegion(const SkRegion& region, SkRegion::Op op) {
409 this->addDrawCommand(new SkClipRegionCommand(region, op));
410 }
412 void SkDebugCanvas::didConcat(const SkMatrix& matrix) {
413 addDrawCommand(new SkConcatCommand(matrix));
414 this->INHERITED::didConcat(matrix);
415 }
417 void SkDebugCanvas::drawBitmap(const SkBitmap& bitmap, SkScalar left,
418 SkScalar top, const SkPaint* paint = NULL) {
419 addDrawCommand(new SkDrawBitmapCommand(bitmap, left, top, paint));
420 }
422 void SkDebugCanvas::drawBitmapRectToRect(const SkBitmap& bitmap,
423 const SkRect* src, const SkRect& dst,
424 const SkPaint* paint,
425 SkCanvas::DrawBitmapRectFlags flags) {
426 addDrawCommand(new SkDrawBitmapRectCommand(bitmap, src, dst, paint, flags));
427 }
429 void SkDebugCanvas::drawBitmapMatrix(const SkBitmap& bitmap,
430 const SkMatrix& matrix, const SkPaint* paint) {
431 addDrawCommand(new SkDrawBitmapMatrixCommand(bitmap, matrix, paint));
432 }
434 void SkDebugCanvas::drawBitmapNine(const SkBitmap& bitmap,
435 const SkIRect& center, const SkRect& dst, const SkPaint* paint) {
436 addDrawCommand(new SkDrawBitmapNineCommand(bitmap, center, dst, paint));
437 }
439 void SkDebugCanvas::drawData(const void* data, size_t length) {
440 addDrawCommand(new SkDrawDataCommand(data, length));
441 }
443 void SkDebugCanvas::beginCommentGroup(const char* description) {
444 addDrawCommand(new SkBeginCommentGroupCommand(description));
445 }
447 void SkDebugCanvas::addComment(const char* kywd, const char* value) {
448 addDrawCommand(new SkCommentCommand(kywd, value));
449 }
451 void SkDebugCanvas::endCommentGroup() {
452 addDrawCommand(new SkEndCommentGroupCommand());
453 }
455 void SkDebugCanvas::drawOval(const SkRect& oval, const SkPaint& paint) {
456 addDrawCommand(new SkDrawOvalCommand(oval, paint));
457 }
459 void SkDebugCanvas::drawPaint(const SkPaint& paint) {
460 addDrawCommand(new SkDrawPaintCommand(paint));
461 }
463 void SkDebugCanvas::drawPath(const SkPath& path, const SkPaint& paint) {
464 addDrawCommand(new SkDrawPathCommand(path, paint));
465 }
467 void SkDebugCanvas::drawPicture(SkPicture& picture) {
468 addDrawCommand(new SkDrawPictureCommand(picture));
469 }
471 void SkDebugCanvas::drawPoints(PointMode mode, size_t count,
472 const SkPoint pts[], const SkPaint& paint) {
473 addDrawCommand(new SkDrawPointsCommand(mode, count, pts, paint));
474 }
476 void SkDebugCanvas::drawPosText(const void* text, size_t byteLength,
477 const SkPoint pos[], const SkPaint& paint) {
478 addDrawCommand(new SkDrawPosTextCommand(text, byteLength, pos, paint));
479 }
481 void SkDebugCanvas::drawPosTextH(const void* text, size_t byteLength,
482 const SkScalar xpos[], SkScalar constY, const SkPaint& paint) {
483 addDrawCommand(
484 new SkDrawPosTextHCommand(text, byteLength, xpos, constY, paint));
485 }
487 void SkDebugCanvas::drawRect(const SkRect& rect, const SkPaint& paint) {
488 // NOTE(chudy): Messing up when renamed to DrawRect... Why?
489 addDrawCommand(new SkDrawRectCommand(rect, paint));
490 }
492 void SkDebugCanvas::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
493 addDrawCommand(new SkDrawRRectCommand(rrect, paint));
494 }
496 void SkDebugCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
497 const SkPaint& paint) {
498 this->addDrawCommand(new SkDrawDRRectCommand(outer, inner, paint));
499 }
501 void SkDebugCanvas::drawSprite(const SkBitmap& bitmap, int left, int top,
502 const SkPaint* paint = NULL) {
503 addDrawCommand(new SkDrawSpriteCommand(bitmap, left, top, paint));
504 }
506 void SkDebugCanvas::drawText(const void* text, size_t byteLength, SkScalar x,
507 SkScalar y, const SkPaint& paint) {
508 addDrawCommand(new SkDrawTextCommand(text, byteLength, x, y, paint));
509 }
511 void SkDebugCanvas::drawTextOnPath(const void* text, size_t byteLength,
512 const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) {
513 addDrawCommand(
514 new SkDrawTextOnPathCommand(text, byteLength, path, matrix, paint));
515 }
517 void SkDebugCanvas::drawVertices(VertexMode vmode, int vertexCount,
518 const SkPoint vertices[], const SkPoint texs[], const SkColor colors[],
519 SkXfermode*, const uint16_t indices[], int indexCount,
520 const SkPaint& paint) {
521 addDrawCommand(new SkDrawVerticesCommand(vmode, vertexCount, vertices,
522 texs, colors, NULL, indices, indexCount, paint));
523 }
525 void SkDebugCanvas::onPushCull(const SkRect& cullRect) {
526 this->addDrawCommand(new SkPushCullCommand(cullRect));
527 }
529 void SkDebugCanvas::onPopCull() {
530 this->addDrawCommand(new SkPopCullCommand());
531 }
533 void SkDebugCanvas::willRestore() {
534 this->addDrawCommand(new SkRestoreCommand());
535 this->INHERITED::willRestore();
536 }
538 void SkDebugCanvas::didRotate(SkScalar degrees) {
539 addDrawCommand(new SkRotateCommand(degrees));
540 this->INHERITED::didRotate(degrees);
541 }
543 void SkDebugCanvas::willSave(SaveFlags flags) {
544 this->addDrawCommand(new SkSaveCommand(flags));
545 this->INHERITED::willSave(flags);
546 }
548 SkCanvas::SaveLayerStrategy SkDebugCanvas::willSaveLayer(const SkRect* bounds, const SkPaint* paint,
549 SaveFlags flags) {
550 this->addDrawCommand(new SkSaveLayerCommand(bounds, paint, flags));
551 this->INHERITED::willSaveLayer(bounds, paint, flags);
552 // No need for a full layer.
553 return kNoLayer_SaveLayerStrategy;
554 }
556 void SkDebugCanvas::didScale(SkScalar sx, SkScalar sy) {
557 addDrawCommand(new SkScaleCommand(sx, sy));
558 this->INHERITED::didScale(sx, sy);
559 }
561 void SkDebugCanvas::didSetMatrix(const SkMatrix& matrix) {
562 addDrawCommand(new SkSetMatrixCommand(matrix));
563 this->INHERITED::didSetMatrix(matrix);
564 }
566 void SkDebugCanvas::didSkew(SkScalar sx, SkScalar sy) {
567 addDrawCommand(new SkSkewCommand(sx, sy));
568 this->INHERITED::didSkew(sx, sy);
569 }
571 void SkDebugCanvas::didTranslate(SkScalar dx, SkScalar dy) {
572 addDrawCommand(new SkTranslateCommand(dx, dy));
573 this->INHERITED::didTranslate(dx, dy);
574 }
576 void SkDebugCanvas::toggleCommand(int index, bool toggle) {
577 SkASSERT(index < fCommandVector.count());
578 fCommandVector[index]->setVisible(toggle);
579 }