📄 imageskia.cpp
字号:
computeResamplingMode(bitmap, srcRect.width(), srcRect.height(), SkScalarToFloat(destRect.width()), SkScalarToFloat(destRect.height())); if (resampling == RESAMPLE_AWESOME) { drawResampledBitmap(*canvas, paint, bitmap, srcRect, destRect); } else { // No resampling necessary, we can just draw the bitmap. We want to // filter it if we decided to do linear interpolation above, or if there // is something interesting going on with the matrix (like a rotation). // Note: for serialization, we will want to subset the bitmap first so // we don't send extra pixels. canvas->drawBitmapRect(bitmap, &srcRect, destRect, &paint); }}// Transforms the given dimensions with the given matrix. Used to see how big// images will be once transformed.static void TransformDimensions(const SkMatrix& matrix, float srcWidth, float srcHeight, float* destWidth, float* destHeight) { // Transform 3 points to see how long each side of the bitmap will be. SkPoint src_points[3]; // (0, 0), (width, 0), (0, height). src_points[0].set(0, 0); src_points[1].set(SkFloatToScalar(srcWidth), 0); src_points[2].set(0, SkFloatToScalar(srcHeight)); // Now measure the length of the two transformed vectors relative to the // transformed origin to see how big the bitmap will be. Note: for skews, // this isn't the best thing, but we don't have skews. SkPoint dest_points[3]; matrix.mapPoints(dest_points, src_points, 3); *destWidth = SkScalarToFloat((dest_points[1] - dest_points[0]).length()); *destHeight = SkScalarToFloat((dest_points[2] - dest_points[0]).length());}// A helper method for translating negative width and height values.static FloatRect normalizeRect(const FloatRect& rect){ FloatRect norm = rect; if (norm.width() < 0) { norm.setX(norm.x() + norm.width()); norm.setWidth(-norm.width()); } if (norm.height() < 0) { norm.setY(norm.y() + norm.height()); norm.setHeight(-norm.height()); } return norm;}bool FrameData::clear(bool clearMetadata){ if (clearMetadata) m_haveMetadata = false; if (m_frame) { // ImageSource::createFrameAtIndex() allocated |m_frame| and passed // ownership to BitmapImage; we must delete it here. delete m_frame; m_frame = 0; return true; } return false;}PassRefPtr<Image> Image::loadPlatformResource(const char *name){ return ChromiumBridge::loadPlatformImageResource(name);}void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect, const TransformationMatrix& patternTransform, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect){ if (destRect.isEmpty() || floatSrcRect.isEmpty()) return; // nothing to draw NativeImageSkia* bitmap = nativeImageForCurrentFrame(); if (!bitmap) return; // This is a very inexpensive operation. It will generate a new bitmap but // it will internally reference the old bitmap's pixels, adjusting the row // stride so the extra pixels appear as padding to the subsetted bitmap. SkBitmap srcSubset; SkIRect srcRect = enclosingIntRect(floatSrcRect); bitmap->extractSubset(&srcSubset, srcRect); SkBitmap resampled; SkShader* shader; // Figure out what size the bitmap will be in the destination. The // destination rect is the bounds of the pattern, we need to use the // matrix to see how bit it will be. float destBitmapWidth, destBitmapHeight; TransformDimensions(patternTransform, srcRect.width(), srcRect.height(), &destBitmapWidth, &destBitmapHeight); // Compute the resampling mode. ResamplingMode resampling; if (context->platformContext()->isPrinting()) resampling = RESAMPLE_LINEAR; else { resampling = computeResamplingMode(*bitmap, srcRect.width(), srcRect.height(), destBitmapWidth, destBitmapHeight); } // Load the transform WebKit requested. SkMatrix matrix(patternTransform); if (resampling == RESAMPLE_AWESOME) { // Do nice resampling. SkBitmap resampled = skia::ImageOperations::Resize(srcSubset, skia::ImageOperations::RESIZE_LANCZOS3, static_cast<int>(destBitmapWidth), static_cast<int>(destBitmapHeight)); shader = SkShader::CreateBitmapShader(resampled, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); // Since we just resized the bitmap, we need to undo the scale set in // the image transform. matrix.setScaleX(SkIntToScalar(1)); matrix.setScaleY(SkIntToScalar(1)); } else { // No need to do nice resampling. shader = SkShader::CreateBitmapShader(srcSubset, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); } // We also need to translate it such that the origin of the pattern is the // origin of the destination rect, which is what WebKit expects. Skia uses // the coordinate system origin as the base for the patter. If WebKit wants // a shifted image, it will shift it from there using the patternTransform. float adjustedX = phase.x() + floatSrcRect.x() * narrowPrecisionToFloat(patternTransform.a()); float adjustedY = phase.y() + floatSrcRect.y() * narrowPrecisionToFloat(patternTransform.d()); matrix.postTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjustedY)); shader->setLocalMatrix(matrix); SkPaint paint; paint.setShader(shader)->unref(); paint.setPorterDuffXfermode(WebCoreCompositeToSkiaComposite(compositeOp)); paint.setFilterBitmap(resampling == RESAMPLE_LINEAR); context->platformContext()->paintSkPaint(destRect, paint);}// ================================================// BitmapImage Class// ================================================// FIXME: These should go to BitmapImageSkia.cppvoid BitmapImage::initPlatformData(){ // This is not used. On Mac, the "platform" data is a cache of some OS // specific versions of the image that are created is some cases. These // aren't normally used, it is equivalent to getHBITMAP on Windows, and // the platform data is the cache.}void BitmapImage::invalidatePlatformData(){ // See initPlatformData above.}void BitmapImage::checkForSolidColor(){ m_checkedForSolidColor = true;}void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp){ if (!m_source.initialized()) return; // Spin the animation to the correct frame before we try to draw it, so we // don't draw an old frame and then immediately need to draw a newer one, // causing flicker and wasting CPU. startAnimation(); const NativeImageSkia* bm = nativeImageForCurrentFrame(); if (!bm) return; // It's too early and we don't have an image yet. FloatRect normDstRect = normalizeRect(dstRect); FloatRect normSrcRect = normalizeRect(srcRect); if (normSrcRect.isEmpty() || normDstRect.isEmpty()) return; // Nothing to draw. paintSkBitmap(ctxt->platformContext(), *bm, enclosingIntRect(normSrcRect), enclosingIntRect(normDstRect), WebCoreCompositeToSkiaComposite(compositeOp));}// FIXME: These should go into BitmapImageSingleFrameSkia.cppvoid BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp){ FloatRect normDstRect = normalizeRect(dstRect); FloatRect normSrcRect = normalizeRect(srcRect); if (normSrcRect.isEmpty() || normDstRect.isEmpty()) return; // Nothing to draw. paintSkBitmap(ctxt->platformContext(), m_nativeImage, enclosingIntRect(normSrcRect), enclosingIntRect(normDstRect), WebCoreCompositeToSkiaComposite(compositeOp));}PassRefPtr<BitmapImageSingleFrameSkia> BitmapImageSingleFrameSkia::create(const SkBitmap& bitmap){ RefPtr<BitmapImageSingleFrameSkia> image(adoptRef(new BitmapImageSingleFrameSkia())); if (!bitmap.copyTo(&image->m_nativeImage, bitmap.config())) return 0; return image.release();}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -