📄 transparencywin.cpp
字号:
TransformationMatrix mapping; mapping.translate(-m_transformedSourceRect.x(), -m_transformedSourceRect.y()); if (m_transformMode == Untransform){ // Compute the inverse mapping from the canvas space to the // coordinate space of our bitmap. mapping = m_orgTransform.inverse() * mapping; } compositeToCopy(*m_destContext, *m_drawContext, mapping); // Save the reference layer so we can tell what changed. SkCanvas referenceCanvas(*m_referenceBitmap); referenceCanvas.drawBitmap(bitmapForContext(*m_drawContext), 0, 0); // Layer rect represents the part of the original layer.}void TransparencyWin::setupLayerForTextComposite(){ ASSERT(m_transformMode == KeepTransform); // Fall through to filling with white. setupLayerForWhiteLayer();}void TransparencyWin::setupLayerForWhiteLayer(){ initializeNewContext(); m_drawContext->fillRect(IntRect(IntPoint(0, 0), m_layerSize), Color::white); // Layer rect represents the part of the original layer.}void TransparencyWin::setupTransform(const IntRect& region){ switch (m_transformMode) { case KeepTransform: setupTransformForKeepTransform(region); break; case Untransform: setupTransformForUntransform(); break; case ScaleTransform: setupTransformForScaleTransform(); break; }}void TransparencyWin::setupTransformForKeepTransform(const IntRect& region){ if (m_layerMode != NoLayer) { // Need to save things since we're modifying the transform. m_drawContext->save(); m_savedOnDrawContext = true; // Account for the fact that the layer may be offset from the // original. This only happens when we create a layer that has the // same coordinate space as the parent. TransformationMatrix xform; xform.translate(-m_transformedSourceRect.x(), -m_transformedSourceRect.y()); // We're making a layer, so apply the old transform to the new one // so it's maintained. We know the new layer has the identity // transform now, we we can just multiply it. xform = m_orgTransform * xform; m_drawContext->concatCTM(xform); } m_drawRect = m_sourceRect;}void TransparencyWin::setupTransformForUntransform(){ ASSERT(m_layerMode != NoLayer); // We now have a new layer with the identity transform, which is the // Untransformed space we'll use for drawing. m_drawRect = IntRect(IntPoint(0, 0), m_layerSize);}void TransparencyWin::setupTransformForScaleTransform(){ if (m_layerMode == NoLayer) { // Need to save things since we're modifying the layer. m_drawContext->save(); m_savedOnDrawContext = true; // Undo the transform on the current layer when we're re-using the // current one. m_drawContext->concatCTM(m_drawContext->getCTM().inverse()); // We're drawing to the original layer with just a different size. m_drawRect = m_transformedSourceRect; } else { // Just go ahead and use the layer's coordinate space to draw into. // It will have the scaled size, and an identity transform loaded. m_drawRect = IntRect(IntPoint(0, 0), m_layerSize); }}void TransparencyWin::setTextCompositeColor(Color color){ m_textCompositeColor = color;}void TransparencyWin::initializeNewContext(){ int pixelSize = m_layerSize.width() * m_layerSize.height(); if (pixelSize > maxCachedBufferPixelSize) { // Create a 1-off buffer for drawing into. We only need the reference // buffer if we're making an OpaqueCompositeLayer. bool needReferenceBitmap = m_layerMode == OpaqueCompositeLayer; m_ownedBuffers.set(new OwnedBuffers(m_layerSize, needReferenceBitmap)); m_layerBuffer = m_ownedBuffers->destBitmap(); m_drawContext = m_layerBuffer->context(); if (needReferenceBitmap) m_referenceBitmap = m_ownedBuffers->referenceBitmap(); return; } if (m_cachedBuffers && m_cachedBuffers->canHandleSize(m_layerSize)) { // We can re-use the existing buffer. We don't need to clear it since // all layer modes will clear it in their initialization. m_layerBuffer = m_cachedBuffers->destBitmap(); m_drawContext = m_cachedBuffers->destBitmap()->context(); bitmapForContext(*m_drawContext).eraseARGB(0, 0, 0, 0); m_referenceBitmap = m_cachedBuffers->referenceBitmap(); m_referenceBitmap->eraseARGB(0, 0, 0, 0); return; } // Create a new cached buffer. if (m_cachedBuffers) delete m_cachedBuffers; m_cachedBuffers = new OwnedBuffers(m_layerSize, true); m_layerBuffer = m_cachedBuffers->destBitmap(); m_drawContext = m_cachedBuffers->destBitmap()->context(); m_referenceBitmap = m_cachedBuffers->referenceBitmap();}void TransparencyWin::compositeOpaqueComposite(){ SkCanvas* destCanvas = canvasForContext(*m_destContext); destCanvas->save(); SkBitmap* bitmap = const_cast<SkBitmap*>( &bitmapForContext(*m_layerBuffer->context())); // This function will be called for WhiteLayer as well, which we don't want // to change. if (m_layerMode == OpaqueCompositeLayer) { // Fix up our bitmap, making it contain only the pixels which changed // and transparent everywhere else. SkAutoLockPixels sourceLock(*m_referenceBitmap); SkAutoLockPixels lock(*bitmap); for (int y = 0; y < bitmap->height(); y++) { uint32_t* source = m_referenceBitmap->getAddr32(0, y); uint32_t* dest = bitmap->getAddr32(0, y); for (int x = 0; x < bitmap->width(); x++) { // Clear out any pixels that were untouched. if (dest[x] == source[x]) dest[x] = 0; else dest[x] |= (0xFF << SK_A32_SHIFT); } } } else makeLayerOpaque(); SkRect destRect; if (m_transformMode != Untransform) { // We want to use Untransformed space. // // Note that we DON'T call m_layerBuffer->image() here. This actually // makes a copy of the image, which is unnecessary and slow. Instead, we // just draw the image from inside the destination context. SkMatrix identity; identity.reset(); destCanvas->setMatrix(identity); destRect.set(m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom()); } else destRect.set(m_sourceRect.x(), m_sourceRect.y(), m_sourceRect.right(), m_sourceRect.bottom()); SkPaint paint; paint.setFilterBitmap(true); paint.setAntiAlias(true); // Note that we need to specify the source layer subset, since the bitmap // may have been cached and it could be larger than what we're using. SkIRect sourceRect = { 0, 0, m_layerSize.width(), m_layerSize.height() }; destCanvas->drawBitmapRect(*bitmap, &sourceRect, destRect, &paint); destCanvas->restore();}void TransparencyWin::compositeTextComposite(){ const SkBitmap& bitmap = m_layerBuffer->context()->platformContext()->canvas()->getTopPlatformDevice().accessBitmap(true); SkColor textColor = m_textCompositeColor.rgb(); for (int y = 0; y < m_layerSize.height(); y++) { uint32_t* row = bitmap.getAddr32(0, y); for (int x = 0; x < m_layerSize.width(); x++) { // The alpha is the average of the R, G, and B channels. int alpha = (SkGetPackedR32(row[x]) + SkGetPackedG32(row[x]) + SkGetPackedB32(row[x])) / 3; // Apply that alpha to the text color and write the result. row[x] = SkAlphaMulQ(textColor, SkAlpha255To256(255 - alpha)); } } // Now the layer has text with the proper color and opacity. SkCanvas* destCanvas = canvasForContext(*m_destContext); // We want to use Untransformed space (see above) SkMatrix identity; identity.reset(); destCanvas->setMatrix(identity); SkRect destRect = { m_transformedSourceRect.x(), m_transformedSourceRect.y(), m_transformedSourceRect.right(), m_transformedSourceRect.bottom() }; // Note that we need to specify the source layer subset, since the bitmap // may have been cached and it could be larger than what we're using. SkIRect sourceRect = { 0, 0, m_layerSize.width(), m_layerSize.height() }; destCanvas->drawBitmapRect(bitmap, &sourceRect, destRect, 0); destCanvas->restore();}void TransparencyWin::makeLayerOpaque(){ SkBitmap& bitmap = const_cast<SkBitmap&>(m_drawContext->platformContext()-> canvas()->getTopPlatformDevice().accessBitmap(true)); for (int y = 0; y < m_layerSize.height(); y++) { uint32_t* row = bitmap.getAddr32(0, y); for (int x = 0; x < m_layerSize.width(); x++) row[x] |= 0xFF000000; }}} // namespace WebCore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -