*/
#include "SkBBoxRecord.h"
+#include "SkPatchUtils.h"
+
+SkBBoxRecord::~SkBBoxRecord() {
+ fSaveStack.deleteAll();
+}
void SkBBoxRecord::drawOval(const SkRect& rect, const SkPaint& paint) {
if (this->transformBounds(rect, &paint)) {
}
}
+// Hack to work-around https://code.google.com/p/chromium/issues/detail?id=373785
+// This logic assums that 'pad' is enough to add to the left and right to account for
+// big glyphs. For the font in question (a logo font) the glyphs is much wider than just
+// the pointsize (approx 3x wider).
+// As a temp work-around, we scale-up pad.
+// A more correct fix might be to add fontmetrics.fMaxX, but we don't have that value in hand
+// at the moment, and (possibly) the value in the font may not be accurate (but who knows).
+//
+static SkScalar hack_373785_amend_pad(SkScalar pad) {
+ return pad * 4;
+}
+
void SkBBoxRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
const SkPaint& paint) {
SkRect bbox;
// pad on left and right by half of max vertical glyph extents
SkScalar pad = (metrics.fTop - metrics.fBottom) / 2;
+ pad = hack_373785_amend_pad(pad);
bbox.fLeft += pad;
bbox.fRight -= pad;
}
// pad horizontally by max glyph height
+ pad = hack_373785_amend_pad(pad);
bbox.fLeft += pad;
bbox.fRight -= pad;
}
}
-void SkBBoxRecord::drawPicture(SkPicture& picture) {
- if (picture.width() > 0 && picture.height() > 0 &&
- this->transformBounds(SkRect::MakeWH(picture.width(), picture.height()), NULL)) {
- INHERITED::drawPicture(picture);
+void SkBBoxRecord::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
+ const SkPoint texCoords[4], SkXfermode* xmode,
+ const SkPaint& paint) {
+ SkRect bbox;
+ bbox.set(cubics, SkPatchUtils::kNumCtrlPts);
+ if (this->transformBounds(bbox, &paint)) {
+ INHERITED::onDrawPatch(cubics, colors, texCoords, xmode, paint);
}
}
+void SkBBoxRecord::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
+ const SkPaint* paint) {
+ SkRect bounds = SkRect::MakeWH(SkIntToScalar(picture->width()),
+ SkIntToScalar(picture->height()));
+ // todo: wonder if we should allow passing an optional matrix to transformBounds so we don't
+ // end up transforming the rect twice.
+ if (matrix) {
+ matrix->mapRect(&bounds);
+ }
+ if (this->transformBounds(bounds, paint)) {
+ this->INHERITED::onDrawPicture(picture, matrix, paint);
+ }
+}
+
+void SkBBoxRecord::willSave() {
+ fSaveStack.push(NULL);
+ this->INHERITED::willSave();
+}
+
+SkCanvas::SaveLayerStrategy SkBBoxRecord::willSaveLayer(const SkRect* bounds,
+ const SkPaint* paint,
+ SaveFlags flags) {
+ // Image filters can affect the effective bounds of primitives drawn inside saveLayer().
+ // Copy the paint so we can compute the modified bounds in transformBounds().
+ fSaveStack.push(paint && paint->getImageFilter() ? new SkPaint(*paint) : NULL);
+ return this->INHERITED::willSaveLayer(bounds, paint, flags);
+}
+
+void SkBBoxRecord::willRestore() {
+ delete fSaveStack.top();
+ fSaveStack.pop();
+ this->INHERITED::willRestore();
+}
+
bool SkBBoxRecord::transformBounds(const SkRect& bounds, const SkPaint* paint) {
SkRect outBounds = bounds;
outBounds.sort();
}
}
+ for (int i = fSaveStack.count() - 1; i >= 0; --i) {
+ const SkPaint* paint = fSaveStack.getAt(i);
+ if (paint && paint->canComputeFastBounds()) {
+ SkRect temp;
+ outBounds = paint->computeFastBounds(outBounds, &temp);
+ }
+ }
+
if (!outBounds.isEmpty() && !this->quickReject(outBounds)) {
this->getTotalMatrix().mapRect(&outBounds);
this->handleBBox(outBounds);