15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "skia/ext/pixel_ref_utils.h" 63240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <algorithm> 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmapDevice.h" 103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkCanvas.h" 113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkData.h" 123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkDraw.h" 133240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkPixelRef.h" 143240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkRRect.h" 153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkRect.h" 163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/include/core/SkShader.h" 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "third_party/skia/include/utils/SkNoSaveLayerCanvas.h" 183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "third_party/skia/src/core/SkRasterClip.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace skia { 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// URI label for a discardable SkPixelRef. 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const char kLabelDiscardable[] = "discardable"; 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class DiscardablePixelRefSet { 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscardablePixelRefSet( 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs) 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) : pixel_refs_(pixel_refs) {} 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void Add(SkPixelRef* pixel_ref, const SkRect& rect) { 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Only save discardable pixel refs. 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pixel_ref->getURI() && 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !strcmp(pixel_ref->getURI(), kLabelDiscardable)) { 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PixelRefUtils::PositionPixelRef position_pixel_ref; 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) position_pixel_ref.pixel_ref = pixel_ref; 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) position_pixel_ref.pixel_ref_rect = rect; 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pixel_refs_->push_back(position_pixel_ref); 41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PixelRefUtils::PositionPixelRef>* pixel_refs_; 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class GatherPixelRefDevice : public SkBitmapDevice { 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public: 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GatherPixelRefDevice(const SkBitmap& bm, 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscardablePixelRefSet* pixel_ref_set) 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : SkBitmapDevice(bm), pixel_ref_set_(pixel_ref_set) {} 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void clear(SkColor color) SK_OVERRIDE {} 55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) SK_OVERRIDE { 56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetBitmapFromPaint(paint, &bitmap)) { 58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect clip_rect = SkRect::Make(draw.fRC->getBounds()); 598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AddBitmap(bitmap, clip_rect); 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawPoints(const SkDraw& draw, 64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkCanvas::PointMode mode, 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t count, 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPoint points[], 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!GetBitmapFromPaint(paint, &bitmap)) 70868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 71868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 72868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (count == 0) 73868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPoint min_point = points[0]; 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPoint max_point = points[0]; 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 1; i < count; ++i) { 78868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPoint& point = points[i]; 79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.set(std::min(min_point.x(), point.x()), 80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::min(min_point.y(), point.y())); 81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_point.set(std::max(max_point.x(), point.x()), 82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::max(max_point.y(), point.y())); 83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 85868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bounds = SkRect::MakeLTRB( 86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.x(), min_point.y(), max_point.x(), max_point.y()); 87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, bounds, paint); 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawRect(const SkDraw& draw, 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkRect& rect, 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetBitmapFromPaint(paint, &bitmap)) { 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect mapped_rect; 96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) draw.fMatrix->mapRect(&mapped_rect, rect); 97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) mapped_rect.intersect(SkRect::Make(draw.fRC->getBounds())); 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddBitmap(bitmap, mapped_rect); 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawOval(const SkDraw& draw, 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkRect& rect, 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, rect, paint); 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawRRect(const SkDraw& draw, 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkRRect& rect, 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, rect.rect(), paint); 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawPath(const SkDraw& draw, 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPath& path, 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint, 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkMatrix* pre_path_matrix, 115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool path_is_mutable) SK_OVERRIDE { 116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!GetBitmapFromPaint(paint, &bitmap)) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect path_bounds = path.getBounds(); 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect final_rect; 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pre_path_matrix != NULL) 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pre_path_matrix->mapRect(&final_rect, path_bounds); 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) final_rect = path_bounds; 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, final_rect, paint); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawBitmap(const SkDraw& draw, 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& bitmap, 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkMatrix& matrix, 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkMatrix total_matrix; 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) total_matrix.setConcat(*draw.fMatrix, matrix); 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bitmap_rect = SkRect::MakeWH(bitmap.width(), bitmap.height()); 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect mapped_rect; 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) total_matrix.mapRect(&mapped_rect, bitmap_rect); 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddBitmap(bitmap, mapped_rect); 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap paint_bitmap; 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetBitmapFromPaint(paint, &paint_bitmap)) 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddBitmap(paint_bitmap, mapped_rect); 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawBitmapRect(const SkDraw& draw, 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& bitmap, 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkRect* src_or_null, 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkRect& dst, 1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const SkPaint& paint, 1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SkCanvas::DrawBitmapRectFlags flags) SK_OVERRIDE { 151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bitmap_rect = SkRect::MakeWH(bitmap.width(), bitmap.height()); 152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkMatrix matrix; 153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matrix.setRectToRect(bitmap_rect, dst, SkMatrix::kFill_ScaleToFit); 154558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch GatherPixelRefDevice::drawBitmap(draw, bitmap, matrix, paint); 155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawSprite(const SkDraw& draw, 157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkBitmap& bitmap, 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int x, 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int y, 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Sprites aren't affected by current matrix, so we can't reuse drawRect. 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkMatrix matrix; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matrix.setTranslate(x, y); 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bitmap_rect = SkRect::MakeWH(bitmap.width(), bitmap.height()); 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect mapped_rect; 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) matrix.mapRect(&mapped_rect, bitmap_rect); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddBitmap(bitmap, mapped_rect); 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap paint_bitmap; 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (GetBitmapFromPaint(paint, &paint_bitmap)) 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddBitmap(paint_bitmap, mapped_rect); 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawText(const SkDraw& draw, 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* text, 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t len, 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar x, 178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar y, 179868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!GetBitmapFromPaint(paint, &bitmap)) 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 184868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Math is borrowed from SkBBoxRecord 185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bounds; 186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) paint.measureText(text, len, &bounds); 187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPaint::FontMetrics metrics; 188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) paint.getFontMetrics(&metrics); 189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (paint.isVerticalText()) { 191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar h = bounds.fBottom - bounds.fTop; 192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (paint.getTextAlign() == SkPaint::kCenter_Align) { 193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop -= h / 2; 194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom -= h / 2; 195868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom += metrics.fBottom; 197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop += metrics.fTop; 198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 199868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar w = bounds.fRight - bounds.fLeft; 200868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (paint.getTextAlign() == SkPaint::kCenter_Align) { 201868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft -= w / 2; 202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight -= w / 2; 203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (paint.getTextAlign() == SkPaint::kRight_Align) { 204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft -= w; 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight -= w; 206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop = metrics.fTop; 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom = metrics.fBottom; 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 211868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; 212868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft -= pad; 213868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight += pad; 214868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft += x; 215868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight += x; 216868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop += y; 217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom += y; 218868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 219868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, bounds, paint); 220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawPosText(const SkDraw& draw, 222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* text, 223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t len, 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkScalar pos[], 225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar const_y, 226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int scalars_per_pos, 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!GetBitmapFromPaint(paint, &bitmap)) 230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (len == 0) 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Similar to SkDraw asserts. 236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkASSERT(scalars_per_pos == 1 || scalars_per_pos == 2); 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPoint min_point; 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPoint max_point; 240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (scalars_per_pos == 1) { 241868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.set(pos[0], const_y); 242868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_point.set(pos[0], const_y); 243868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else if (scalars_per_pos == 2) { 244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.set(pos[0], const_y + pos[1]); 245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_point.set(pos[0], const_y + pos[1]); 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < len; ++i) { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar x = pos[i * scalars_per_pos]; 250868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar y = const_y; 251868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (scalars_per_pos == 2) 252868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) y += pos[i * scalars_per_pos + 1]; 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.set(std::min(x, min_point.x()), std::min(y, min_point.y())); 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) max_point.set(std::max(x, max_point.x()), std::max(y, max_point.y())); 256868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 257868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 258868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bounds = SkRect::MakeLTRB( 259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) min_point.x(), min_point.y(), max_point.x(), max_point.y()); 260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Math is borrowed from SkBBoxRecord 262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPaint::FontMetrics metrics; 263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) paint.getFontMetrics(&metrics); 264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop += metrics.fTop; 266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom += metrics.fBottom; 267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; 269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft += pad; 270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight -= pad; 271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 272868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, bounds, paint); 273868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawTextOnPath(const SkDraw& draw, 275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const void* text, 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) size_t len, 277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPath& path, 278868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkMatrix* matrix, 279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap bitmap; 281868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!GetBitmapFromPaint(paint, &bitmap)) 282868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Math is borrowed from SkBBoxRecord 285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRect bounds = path.getBounds(); 286868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPaint::FontMetrics metrics; 287868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) paint.getFontMetrics(&metrics); 288868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkScalar pad = metrics.fTop; 290868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fLeft += pad; 291868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fRight -= pad; 292868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fTop += pad; 293868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bounds.fBottom -= pad; 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawRect(draw, bounds, paint); 296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawVertices(const SkDraw& draw, 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkCanvas::VertexMode, 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int vertex_count, 300868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPoint verts[], 301868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPoint texs[], 302868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkColor colors[], 303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkXfermode* xmode, 304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const uint16_t indices[], 305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int index_count, 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint& paint) SK_OVERRIDE { 307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice::drawPoints( 308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) draw, SkCanvas::kPolygon_PointMode, vertex_count, verts, paint); 309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) virtual void drawDevice(const SkDraw&, 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) SkBaseDevice*, 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int x, 313868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int y, 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const SkPaint&) SK_OVERRIDE {} 315868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 316868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) protected: 317effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch virtual bool onReadPixels(const SkImageInfo& info, 318effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void* pixels, 319effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t rowBytes, 320effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int x, 321effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch int y) SK_OVERRIDE { 322effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return false; 323effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 324effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool onWritePixels(const SkImageInfo& info, 326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const void* pixels, 327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t rowBytes, 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int x, 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) int y) SK_OVERRIDE { 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return false; 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 332868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) private: 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscardablePixelRefSet* pixel_ref_set_; 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void AddBitmap(const SkBitmap& bm, const SkRect& rect) { 3378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkRect canvas_rect = SkRect::MakeWH(width(), height()); 3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) SkRect paint_rect = SkRect::MakeEmpty(); 3398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) paint_rect.intersect(rect, canvas_rect); 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixel_ref_set_->Add(bm.pixelRef(), paint_rect); 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool GetBitmapFromPaint(const SkPaint& paint, SkBitmap* bm) { 344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkShader* shader = paint.getShader(); 345868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (shader) { 346868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Check whether the shader is a gradient in order to prevent generation 347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // of bitmaps from gradient shaders, which implement asABitmap. 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (SkShader::kNone_GradientType == shader->asAGradient(NULL)) 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return shader->asABitmap(bm, NULL, NULL); 350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}; 354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PixelRefUtils::GatherDiscardablePixelRefs( 358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkPicture* picture, 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<PositionPixelRef>* pixel_refs) { 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixel_refs->clear(); 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiscardablePixelRefSet pixel_ref_set(pixel_refs); 362868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 363868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkBitmap empty_bitmap; 364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) empty_bitmap.setInfo(SkImageInfo::MakeUnknown(picture->width(), picture->height())); 365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GatherPixelRefDevice device(empty_bitmap, &pixel_ref_set); 367effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SkNoSaveLayerCanvas canvas(&device); 368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 369868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) canvas.clipRect(SkRect::MakeWH(picture->width(), picture->height()), 370868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) SkRegion::kIntersect_Op, 371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) false); 37246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) canvas.drawPicture(picture); 373868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 375868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace skia 376