1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
#include "base/numerics/checked_math.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/image_observer.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.h"
#include "third_party/blink/renderer/platform/transforms/affine_transform.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/gfx/geometry/skia_conversions.h"
#include "v8/include/v8.h"
namespace blink {
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
PaintImage image,
ImageOrientation orientation) {
DCHECK(!image.IsTextureBacked());
return UnacceleratedStaticBitmapImage::Create(std::move(image), orientation);
}
scoped_refptr<StaticBitmapImage> StaticBitmapImage::Create(
sk_sp<SkData> data,
const SkImageInfo& info,
ImageOrientation orientation) {
return UnacceleratedStaticBitmapImage::Create(
SkImages::RasterFromData(info, std::move(data), info.minRowBytes()),
orientation);
}
gfx::Size StaticBitmapImage::SizeWithConfig(SizeConfig config) const {
gfx::Size size = GetSize();
if (config.apply_orientation && orientation_.UsesWidthAsHeight())
size.Transpose();
return size;
}
Vector<uint8_t> StaticBitmapImage::CopyImageData(const SkImageInfo& info,
bool apply_orientation) {
if (info.isEmpty())
return {};
PaintImage paint_image = PaintImageForCurrentFrame();
if (paint_image.GetSkImageInfo().isEmpty())
return {};
wtf_size_t byte_length =
base::checked_cast<wtf_size_t>(info.computeMinByteSize());
if (byte_length > partition_alloc::MaxDirectMapped())
return {};
Vector<uint8_t> dst_buffer(byte_length);
bool read_pixels_successful =
paint_image.readPixels(info, dst_buffer.data(), info.minRowBytes(), 0, 0);
DCHECK(read_pixels_successful);
if (!read_pixels_successful)
return {};
// Orient the data, and re-read the pixels.
if (apply_orientation && !HasDefaultOrientation()) {
paint_image = Image::ResizeAndOrientImage(paint_image, Orientation(),
gfx::Vector2dF(1, 1), 1,
kInterpolationNone);
read_pixels_successful = paint_image.readPixels(info, dst_buffer.data(),
info.minRowBytes(), 0, 0);
DCHECK(read_pixels_successful);
if (!read_pixels_successful)
return {};
}
return dst_buffer;
}
void StaticBitmapImage::DrawHelper(cc::PaintCanvas* canvas,
const cc::PaintFlags& flags,
const gfx::RectF& dst_rect,
const gfx::RectF& src_rect,
const ImageDrawOptions& draw_options,
const PaintImage& image) {
gfx::RectF adjusted_src_rect = src_rect;
adjusted_src_rect.Intersect(gfx::RectF(image.width(), image.height()));
if (dst_rect.IsEmpty() || adjusted_src_rect.IsEmpty())
return; // Nothing to draw.
cc::PaintCanvasAutoRestore auto_restore(canvas, false);
gfx::RectF adjusted_dst_rect = dst_rect;
if (draw_options.respect_orientation &&
orientation_ != ImageOrientationEnum::kDefault) {
canvas->save();
// ImageOrientation expects the origin to be at (0, 0)
canvas->translate(adjusted_dst_rect.x(), adjusted_dst_rect.y());
adjusted_dst_rect.set_origin(gfx::PointF());
canvas->concat(
orientation_.TransformFromDefault(adjusted_dst_rect.size()).ToSkM44());
if (orientation_.UsesWidthAsHeight())
adjusted_dst_rect.set_size(gfx::TransposeSize(adjusted_dst_rect.size()));
}
canvas->drawImageRect(image, gfx::RectFToSkRect(adjusted_src_rect),
gfx::RectFToSkRect(adjusted_dst_rect),
draw_options.sampling_options, &flags,
ToSkiaRectConstraint(draw_options.clamping_mode));
}
} // namespace blink
|