1e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
2e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com/*
3e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com * Copyright 2012 Google Inc.
4e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com *
5e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com * Use of this source code is governed by a BSD-style license that can be
6e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com * found in the LICENSE file.
7e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com */
8e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
9e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com#include "SkBBoxRecord.h"
10e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
115f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.orgvoid SkBBoxRecord::drawOval(const SkRect& rect, const SkPaint& paint) {
125f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org    if (this->transformBounds(rect, &paint)) {
135f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org        INHERITED::drawOval(rect, paint);
145f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org    }
155f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org}
165f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org
175f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.orgvoid SkBBoxRecord::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
185f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org    if (this->transformBounds(rrect.rect(), &paint)) {
195f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org        INHERITED::drawRRect(rrect, paint);
205f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org    }
215f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org}
225f8c8f448673c65c5434cf1e419319eccf34117bjunov@chromium.org
237ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkBBoxRecord::drawRect(const SkRect& rect, const SkPaint& paint) {
24e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(rect, &paint)) {
257ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com        INHERITED::drawRect(rect, paint);
26e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
27e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
28e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
29ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.orgvoid SkBBoxRecord::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
30ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org                                const SkPaint& paint) {
31ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org    if (this->transformBounds(outer.rect(), &paint)) {
32ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org        this->INHERITED::onDrawDRRect(outer, inner, paint);
33ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org    }
34ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org}
35ed9806f5c972513d4141c9d1b5a04ab78b3af4cbcommit-bot@chromium.org
367ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.comvoid SkBBoxRecord::drawPath(const SkPath& path, const SkPaint& paint) {
370c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org    if (path.isInverseFillType()) {
380c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org        // If path is inverse filled, use the current clip bounds as the
390c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org        // path's device-space bounding box.
400c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org        SkIRect clipBounds;
410c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org        if (this->getClipDeviceBounds(&clipBounds)) {
424469938e92d779dff05e745559e67907bbf21e78reed@google.com            this->handleBBox(SkRect::Make(clipBounds));
437ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com            INHERITED::drawPath(path, paint);
440c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org        }
450c8ec2f658a206cbedd0d955167654fae85ad5fbjunov@chromium.org    } else if (this->transformBounds(path.getBounds(), &paint)) {
467ce564cccb246ec56427085872b2e1458fe74bd1bsalomon@google.com        INHERITED::drawPath(path, paint);
47e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
48e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
49e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
50e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawPoints(PointMode mode, size_t count, const SkPoint pts[],
51e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                              const SkPaint& paint) {
52e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox;
536fcd28ba1de83b72f4c8343ccec27d26c127de32reed@google.com    bbox.set(pts, SkToInt(count));
54b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // Small min width value, just to ensure hairline point bounding boxes aren't empty.
55b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // Even though we know hairline primitives are drawn one pixel wide, we do not use a
56b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // minimum of 1 because the playback scale factor is unknown at record time. Later
57b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // outsets will take care of adding additional padding for antialiasing and rounding out
58b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // to integer device coordinates, guaranteeing that the rasterized pixels will be included
59b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // in the computed bounds.
60b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // Note: The device coordinate outset in SkBBoxHierarchyRecord::handleBBox is currently
61b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // done in the recording coordinate space, which is wrong.
62b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    // http://code.google.com/p/skia/issues/detail?id=1021
634b413c8bb123e42ca4b9c7bfa6bc2167283cb84ccommit-bot@chromium.org    static const SkScalar kMinWidth = 0.01f;
64b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    SkScalar halfStrokeWidth = SkMaxScalar(paint.getStrokeWidth(), kMinWidth) / 2;
65b3470c8c421ee8f367673a67c3408507cee04434junov@chromium.org    bbox.outset(halfStrokeWidth, halfStrokeWidth);
66e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, &paint)) {
67e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        INHERITED::drawPoints(mode, count, pts, paint);
68e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
6904ba448579b976369075c675d847ef0f779d40f4skia.committer@gmail.com}
70e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
71e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawPaint(const SkPaint& paint) {
72e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox;
73e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->getClipBounds(&bbox)) {
74e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        if (this->transformBounds(bbox, &paint)) {
75e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            INHERITED::drawPaint(paint);
76e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
77e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
78e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
79e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
80e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::clear(SkColor color) {
81e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkISize size = this->getDeviceSize();
82ec0aa764ebe36aecdfb77286d665fccc85ab204ageorge@mozilla.com    SkRect bbox = {0, 0, SkIntToScalar(size.width()), SkIntToScalar(size.height())};
83e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    this->handleBBox(bbox);
84e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    INHERITED::clear(color);
85e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
86e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
87e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkBBoxRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
88e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com                              const SkPaint& paint) {
89e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox;
90e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    paint.measureText(text, byteLength, &bbox);
91e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkPaint::FontMetrics metrics;
92e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    paint.getFontMetrics(&metrics);
93e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
94e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // Vertical and aligned text need to be offset
95e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (paint.isVerticalText()) {
96e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        SkScalar h = bbox.fBottom - bbox.fTop;
97e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        if (paint.getTextAlign() == SkPaint::kCenter_Align) {
98e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fTop    -= h / 2;
99e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fBottom -= h / 2;
100e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
101e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        // Pad top and bottom with max extents from FontMetrics
102e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        bbox.fBottom += metrics.fBottom;
103e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        bbox.fTop += metrics.fTop;
104e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    } else {
105e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        SkScalar w = bbox.fRight - bbox.fLeft;
106e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        if (paint.getTextAlign() == SkPaint::kCenter_Align) {
107e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fLeft  -= w / 2;
108e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fRight -= w / 2;
109e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        } else if (paint.getTextAlign() == SkPaint::kRight_Align) {
110e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fLeft  -= w;
111e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            bbox.fRight -= w;
112e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
113e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        // Set vertical bounds to max extents from font metrics
114e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        bbox.fTop = metrics.fTop;
115e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        bbox.fBottom = metrics.fBottom;
116e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
117e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
11804ba448579b976369075c675d847ef0f779d40f4skia.committer@gmail.com    // Pad horizontal bounds on each side by half of max vertical extents (this is sort of
119e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // arbitrary, but seems to produce reasonable results, if there were a way of getting max
120e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // glyph X-extents to pad by, that may be better here, but FontMetrics fXMin and fXMax seem
121e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // incorrect on most platforms (too small in Linux, never even set in Windows).
122e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkScalar pad = (metrics.fBottom - metrics.fTop) / 2;
123e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fLeft  -= pad;
124e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fRight += pad;
125e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
126e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fLeft += x;
127e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fRight += x;
128e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fTop += y;
129e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fBottom += y;
130e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, &paint)) {
131e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com        INHERITED::onDrawText(text, byteLength, x, y, paint);
132e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
133e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
134e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
135e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top,
136e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                              const SkPaint* paint) {
137e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox = {left, top, left + bitmap.width(), top + bitmap.height()};
138e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, paint)) {
139e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        INHERITED::drawBitmap(bitmap, left, top, paint);
140e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
141e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
142e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
1437112173c3c4cd1b1e7da8cdf971d71f01dd91299reed@google.comvoid SkBBoxRecord::drawBitmapRectToRect(const SkBitmap& bitmap, const SkRect* src,
144eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                                        const SkRect& dst, const SkPaint* paint,
145eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org                                        DrawBitmapRectFlags flags) {
146e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(dst, paint)) {
147eed779d866e1e239bfb9ebc6a225b7345a41adf9commit-bot@chromium.org        INHERITED::drawBitmapRectToRect(bitmap, src, dst, paint, flags);
148e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
149e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
150e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
151e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawBitmapMatrix(const SkBitmap& bitmap, const SkMatrix& mat,
152e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                    const SkPaint* paint) {
153e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkMatrix m = mat;
154ec0aa764ebe36aecdfb77286d665fccc85ab204ageorge@mozilla.com    SkRect bbox = {0, 0, SkIntToScalar(bitmap.width()), SkIntToScalar(bitmap.height())};
155e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    m.mapRect(&bbox);
156e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, paint)) {
157e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        INHERITED::drawBitmapMatrix(bitmap, mat, paint);
158e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
159e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
160e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
161e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
162e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                  const SkRect& dst, const SkPaint* paint) {
163e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(dst, paint)) {
164e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        INHERITED::drawBitmapNine(bitmap, center, dst, paint);
165e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
166e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
167e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
168300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// Hack to work-around https://code.google.com/p/chromium/issues/detail?id=373785
169300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// This logic assums that 'pad' is enough to add to the left and right to account for
170300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// big glyphs. For the font in question (a logo font) the glyphs is much wider than just
171300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// the pointsize (approx 3x wider).
172300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// As a temp work-around, we scale-up pad.
173300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// A more correct fix might be to add fontmetrics.fMaxX, but we don't have that value in hand
174300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org// at the moment, and (possibly) the value in the font may not be accurate (but who knows).
175300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org//
176300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.orgstatic SkScalar hack_373785_amend_pad(SkScalar pad) {
177300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org    return pad * 4;
178300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org}
179300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org
180e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkBBoxRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
181e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com                                 const SkPaint& paint) {
182e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox;
183e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.set(pos, paint.countText(text, byteLength));
184e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkPaint::FontMetrics metrics;
185e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    paint.getFontMetrics(&metrics);
186e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fTop += metrics.fTop;
187e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fBottom += metrics.fBottom;
188e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
189e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // pad on left and right by half of max vertical glyph extents
190e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkScalar pad = (metrics.fTop - metrics.fBottom) / 2;
191300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org    pad = hack_373785_amend_pad(pad);
192e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fLeft += pad;
193e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fRight -= pad;
194e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
195e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, &paint)) {
196e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com        INHERITED::onDrawPosText(text, byteLength, pos, paint);
197e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
198e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
199e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
200e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkBBoxRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
201e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com                                  SkScalar constY, const SkPaint& paint) {
202e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    size_t numChars = paint.countText(text, byteLength);
203cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    if (numChars == 0) {
204cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org        return;
205cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    }
206cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
207cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    const SkFlatData* flatPaintData = this->getFlatPaintData(paint);
208cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    WriteTopBot(paint, *flatPaintData);
209cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
210cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    SkScalar top = flatPaintData->topBot()[0];
211cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    SkScalar bottom = flatPaintData->topBot()[1];
212cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    SkScalar pad = top - bottom;
213cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
214cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    SkRect bbox;
215cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fLeft = SK_ScalarMax;
216cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fRight = SK_ScalarMin;
217cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
218cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    for (size_t i = 0; i < numChars; ++i) {
219cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org        if (xpos[i] < bbox.fLeft) {
220cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org            bbox.fLeft = xpos[i];
221e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
222cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org        if (xpos[i] > bbox.fRight) {
223cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org            bbox.fRight = xpos[i];
224e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
225e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
226cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
227cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    // pad horizontally by max glyph height
228300790e228751661e1245c774b967b6cc50ffa1bcommit-bot@chromium.org    pad = hack_373785_amend_pad(pad);
229cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fLeft  += pad;
230cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fRight -= pad;
231cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
232cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fTop    = top + constY;
233cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    bbox.fBottom = bottom + constY;
234cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org
235cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    if (!this->transformBounds(bbox, &paint)) {
236cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org        return;
237cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    }
238cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    // This is the equivalent of calling:
239cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    //  INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint);
240cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    // but we filled our flat paint beforehand so that we could get font metrics.
241cf7be95b19f283e3c5410f977474f433a1e10dadcommit-bot@chromium.org    drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData);
242e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
243e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
244e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawSprite(const SkBitmap& bitmap, int left, int top,
245e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                              const SkPaint* paint) {
24678c0c30987075821547979de55200c32bcaa3e49junov@chromium.org    SkRect bbox;
24778c0c30987075821547979de55200c32bcaa3e49junov@chromium.org    bbox.set(SkIRect::MakeXYWH(left, top, bitmap.width(), bitmap.height()));
248e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    this->handleBBox(bbox); // directly call handleBBox, matrix is ignored
24978c0c30987075821547979de55200c32bcaa3e49junov@chromium.org    INHERITED::drawSprite(bitmap, left, top, paint);
250e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
251e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
252e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.comvoid SkBBoxRecord::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
253e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com                                    const SkMatrix* matrix, const SkPaint& paint) {
254e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox = path.getBounds();
255e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkPaint::FontMetrics metrics;
256e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    paint.getFontMetrics(&metrics);
257e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
258e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    // pad out all sides by the max glyph height above baseline
259e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkScalar pad = metrics.fTop;
260e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fLeft += pad;
261e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fRight -= pad;
262e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fTop += pad;
263e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.fBottom -= pad;
264e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
265e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, &paint)) {
266e0d9ce890e67d02727ac2811bb456ddb64f827d4reed@google.com        INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, paint);
267e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
268e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
269e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
270e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.comvoid SkBBoxRecord::drawVertices(VertexMode mode, int vertexCount,
271e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                const SkPoint vertices[], const SkPoint texs[],
272e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                const SkColor colors[], SkXfermode* xfer,
273e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                const uint16_t indices[], int indexCount,
274e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                const SkPaint& paint) {
275e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect bbox;
276e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    bbox.set(vertices, vertexCount);
277e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (this->transformBounds(bbox, &paint)) {
278e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        INHERITED::drawVertices(mode, vertexCount, vertices, texs,
279e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                                colors, xfer, indices, indexCount, paint);
280e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
281e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
282e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
2839b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillipsvoid SkBBoxRecord::onDrawPicture(const SkPicture* picture) {
2849b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips    if (picture->width() > 0 && picture->height() > 0 &&
2859b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips        this->transformBounds(SkRect::MakeWH(picture->width(), picture->height()), NULL)) {
2869b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips        this->INHERITED::onDrawPicture(picture);
287e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
288e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
289e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
290e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.combool SkBBoxRecord::transformBounds(const SkRect& bounds, const SkPaint* paint) {
291e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    SkRect outBounds = bounds;
2926006b5641e575181f2d6f1212b8db491b2c2671cjunov@chromium.org    outBounds.sort();
293e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
294e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    if (paint) {
295e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        // account for stroking, path effects, shadows, etc
296e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        if (paint->canComputeFastBounds()) {
297e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            SkRect temp;
2986006b5641e575181f2d6f1212b8db491b2c2671cjunov@chromium.org            outBounds = paint->computeFastBounds(outBounds, &temp);
299e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        } else {
300e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            // set bounds to current clip
301e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            if (!this->getClipBounds(&outBounds)) {
302e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                // current clip is empty
303e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com                return false;
304e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com            }
305e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        }
306e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
307e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
30859a6a2b98302adc4732fc26873043bad1a94e9f1bungeman@google.com    if (!outBounds.isEmpty() && !this->quickReject(outBounds)) {
309e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        this->getTotalMatrix().mapRect(&outBounds);
310e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        this->handleBBox(outBounds);
311e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com        return true;
312e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    }
313e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com
314e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com    return false;
315e0201a4448f5e770cc081ca3425bed528af27f8drileya@google.com}
316