| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2008, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 | 137 |
| 138 return LinearResampling; | 138 return LinearResampling; |
| 139 } | 139 } |
| 140 | 140 |
| 141 static ResamplingMode limitResamplingMode(GraphicsContext* context, ResamplingMo
de resampling) | 141 static ResamplingMode limitResamplingMode(GraphicsContext* context, ResamplingMo
de resampling) |
| 142 { | 142 { |
| 143 switch (context->imageInterpolationQuality()) { | 143 switch (context->imageInterpolationQuality()) { |
| 144 case InterpolationNone: | 144 case InterpolationNone: |
| 145 return NoResampling; | 145 return NoResampling; |
| 146 case InterpolationMedium: | 146 case InterpolationMedium: |
| 147 // For now we treat InterpolationMedium and InterpolationLow the same. | 147 if (resampling == AwesomeResampling) |
| 148 return LinearWithMipmapsResampling; |
| 149 break; |
| 148 case InterpolationLow: | 150 case InterpolationLow: |
| 149 if (resampling == AwesomeResampling) | 151 if (resampling == AwesomeResampling || resampling == LinearWithMipmapsRe
sampling) |
| 150 return LinearResampling; | 152 return LinearResampling; |
| 151 break; | 153 break; |
| 152 case InterpolationHigh: | 154 case InterpolationHigh: |
| 153 case InterpolationDefault: | |
| 154 break; | 155 break; |
| 155 } | 156 } |
| 156 | 157 |
| 157 return resampling; | 158 return resampling; |
| 158 } | 159 } |
| 159 | 160 |
| 161 static SkPaint::FilterLevel convertToSkiaFilterLevel(bool useBicubicFilter, Resa
mplingMode resampling) |
| 162 { |
| 163 if (useBicubicFilter) |
| 164 return SkPaint::kHigh_FilterLevel; |
| 165 |
| 166 switch (resampling) { |
| 167 case LinearWithMipmapsResampling: |
| 168 return SkPaint::kMedium_FilterLevel; |
| 169 case LinearResampling: |
| 170 return SkPaint::kLow_FilterLevel; |
| 171 // AwesomeResampling if useBicubicFilter is false means that we do |
| 172 // a manual high quality resampling before drawing to Skia. |
| 173 case AwesomeResampling: |
| 174 default: |
| 175 return SkPaint::kNone_FilterLevel; |
| 176 } |
| 177 } |
| 178 |
| 160 // This function is used to scale an image and extract a scaled fragment. | 179 // This function is used to scale an image and extract a scaled fragment. |
| 161 // | 180 // |
| 162 // ALGORITHM | 181 // ALGORITHM |
| 163 // | 182 // |
| 164 // Because the scaled image size has to be integers, we approximate the real | 183 // Because the scaled image size has to be integers, we approximate the real |
| 165 // scale with the following formula (only X direction is shown): | 184 // scale with the following formula (only X direction is shown): |
| 166 // | 185 // |
| 167 // scaledImageWidth = round(scaleX * imageRect.width()) | 186 // scaledImageWidth = round(scaleX * imageRect.width()) |
| 168 // approximateScaleX = scaledImageWidth / imageRect.width() | 187 // approximateScaleX = scaledImageWidth / imageRect.width() |
| 169 // | 188 // |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar
get.height())); | 365 SkScalarToFloat(destRectTarget.width()), SkScalarToFloat(destRectTar
get.height())); |
| 347 } | 366 } |
| 348 | 367 |
| 349 if (resampling == NoResampling) { | 368 if (resampling == NoResampling) { |
| 350 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag | 369 // FIXME: This is to not break tests (it results in the filter bitmap fl
ag |
| 351 // being set to true). We need to decide if we respect NoResampling | 370 // being set to true). We need to decide if we respect NoResampling |
| 352 // being returned from computeResamplingMode. | 371 // being returned from computeResamplingMode. |
| 353 resampling = LinearResampling; | 372 resampling = LinearResampling; |
| 354 } | 373 } |
| 355 resampling = limitResamplingMode(context, resampling); | 374 resampling = limitResamplingMode(context, resampling); |
| 356 paint.setFilterBitmap(resampling == LinearResampling); | |
| 357 | 375 |
| 358 bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap()); | 376 bool isLazyDecoded = DeferredImageDecoder::isLazyDecoded(bitmap()); |
| 359 // FIXME: Bicubic filtering in Skia is only applied to defer-decoded images | 377 // FIXME: Bicubic filtering in Skia is only applied to defer-decoded images |
| 360 // as an experiment. Once this filtering code path becomes stable we should | 378 // as an experiment. Once this filtering code path becomes stable we should |
| 361 // turn this on for all cases, including non-defer-decoded images. | 379 // turn this on for all cases, including non-defer-decoded images. |
| 362 bool useBicubicFilter = resampling == AwesomeResampling && isLazyDecoded; | 380 bool useBicubicFilter = resampling == AwesomeResampling && isLazyDecoded; |
| 363 | 381 |
| 364 if (useBicubicFilter) | 382 paint.setFilterLevel(convertToSkiaFilterLevel(useBicubicFilter, resampling))
; |
| 365 paint.setFilterLevel(SkPaint::kHigh_FilterLevel); | |
| 366 | 383 |
| 367 if (resampling == AwesomeResampling && !useBicubicFilter) { | 384 if (resampling == AwesomeResampling && !useBicubicFilter) { |
| 368 // Resample the image and then draw the result to canvas with bilinear | 385 // Resample the image and then draw the result to canvas with bilinear |
| 369 // filtering. | 386 // filtering. |
| 370 drawResampledBitmap(context, paint, srcRect, destRect); | 387 drawResampledBitmap(context, paint, srcRect, destRect); |
| 371 } else { | 388 } else { |
| 372 // We want to filter it if we decided to do interpolation above, or if | 389 // We want to filter it if we decided to do interpolation above, or if |
| 373 // there is something interesting going on with the matrix (like a rotat
ion). | 390 // there is something interesting going on with the matrix (like a rotat
ion). |
| 374 // Note: for serialization, we will want to subset the bitmap first so w
e | 391 // Note: for serialization, we will want to subset the bitmap first so w
e |
| 375 // don't send extra pixels. | 392 // don't send extra pixels. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 // a shifted image, it will shift it from there using the shaderTransform. | 506 // a shifted image, it will shift it from there using the shaderTransform. |
| 490 float adjustedX = phase.x() + normSrcRect.x() * scale.width(); | 507 float adjustedX = phase.x() + normSrcRect.x() * scale.width(); |
| 491 float adjustedY = phase.y() + normSrcRect.y() * scale.height(); | 508 float adjustedY = phase.y() + normSrcRect.y() * scale.height(); |
| 492 shaderTransform.postTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(ad
justedY)); | 509 shaderTransform.postTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(ad
justedY)); |
| 493 shader->setLocalMatrix(shaderTransform); | 510 shader->setLocalMatrix(shaderTransform); |
| 494 | 511 |
| 495 SkPaint paint; | 512 SkPaint paint; |
| 496 paint.setShader(shader.get()); | 513 paint.setShader(shader.get()); |
| 497 paint.setXfermode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode).ge
t()); | 514 paint.setXfermode(WebCoreCompositeToSkiaComposite(compositeOp, blendMode).ge
t()); |
| 498 paint.setColorFilter(context->colorFilter()); | 515 paint.setColorFilter(context->colorFilter()); |
| 516 paint.setFilterLevel(convertToSkiaFilterLevel(useBicubicFilter, resampling))
; |
| 499 | 517 |
| 500 paint.setFilterBitmap(resampling == LinearResampling); | |
| 501 if (useBicubicFilter) | |
| 502 paint.setFilterLevel(SkPaint::kHigh_FilterLevel); | |
| 503 if (isLazyDecoded) | 518 if (isLazyDecoded) |
| 504 PlatformInstrumentation::didDrawLazyPixelRef(bitmap().getGenerationID())
; | 519 PlatformInstrumentation::didDrawLazyPixelRef(bitmap().getGenerationID())
; |
| 505 | 520 |
| 506 context->drawRect(destRect, paint); | 521 context->drawRect(destRect, paint); |
| 507 } | 522 } |
| 508 | 523 |
| 509 bool NativeImageSkia::shouldCacheResampling(const SkISize& scaledImageSize, cons
t SkIRect& scaledImageSubset) const | 524 bool NativeImageSkia::shouldCacheResampling(const SkISize& scaledImageSize, cons
t SkIRect& scaledImageSubset) const |
| 510 { | 525 { |
| 511 // Check whether the requested dimensions match previous request. | 526 // Check whether the requested dimensions match previous request. |
| 512 bool matchesPreviousRequest = m_cachedImageInfo.isEqual(scaledImageSize, sca
ledImageSubset); | 527 bool matchesPreviousRequest = m_cachedImageInfo.isEqual(scaledImageSize, sca
ledImageSubset); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 SkIRect NativeImageSkia::ImageResourceInfo::rectInSubset(const SkIRect& otherSca
ledImageSubset) | 587 SkIRect NativeImageSkia::ImageResourceInfo::rectInSubset(const SkIRect& otherSca
ledImageSubset) |
| 573 { | 588 { |
| 574 if (!scaledImageSubset.contains(otherScaledImageSubset)) | 589 if (!scaledImageSubset.contains(otherScaledImageSubset)) |
| 575 return SkIRect::MakeEmpty(); | 590 return SkIRect::MakeEmpty(); |
| 576 SkIRect subsetRect = otherScaledImageSubset; | 591 SkIRect subsetRect = otherScaledImageSubset; |
| 577 subsetRect.offset(-scaledImageSubset.x(), -scaledImageSubset.y()); | 592 subsetRect.offset(-scaledImageSubset.x(), -scaledImageSubset.y()); |
| 578 return subsetRect; | 593 return subsetRect; |
| 579 } | 594 } |
| 580 | 595 |
| 581 } // namespace WebCore | 596 } // namespace WebCore |
| OLD | NEW |