void GfxCanvasText::paint(GfxPainter &p) { if(_img.isNull()) return; qreal op = p.opacity(); p.setOpacity(op * layerVisible()); QSize _s = _img.size(); QPoint point = getImgPoint(); if(1. != layerScale()) { QMatrix m; m.translate(layerX(), layerY()); m.scale(layerScale(), layerScale()); m.translate(-_size.width() / 2, -_size.height() / 2); m.translate(point.x(), point.y()); p.drawImageTransformed(m, _img, quality().value() != 0.); } else { p.drawImage(int(layerX()) + point.x() - _size.width() / 2, int(layerY()) + point.y() - _size.height() / 2, _img); if(gfx_show_image_bounds) { QRect r(int(layerX()) + point.x() - _size.width() / 2, int(layerY()) + point.y() - _size.height() / 2, _img.width(), _img.height()); p.fillRect(r, QColor(0, 0, 255, 127)); } } p.setOpacity(op); GfxCanvasItem::paint(p); }
void GfxCanvasImage::paint(GfxPainter &p) { if(_img.isNull()) return; qreal op = p.opacity(); p.setOpacity(op * layerVisible()); if(_rotate.value() || 1. != layerScale()) { QMatrix m; m.translate(layerX(), layerY()); m.rotate(_rotate.value()); m.scale(layerScale(), layerScale()); m.translate(-_s.width() / 2, -_s.height() / 2); p.drawImageTransformed(m, _img, quality().value() != 0.); } else { if(subPixelPlacement()) { p.drawImage(qreal(layerX() - qreal(_s.width()) / 2.), int(layerY() - qreal(_s.height()) / 2.), _img); } else { p.drawImage(int(layerX() - qreal(_s.width()) / 2.), int(layerY() - qreal(_s.height()) / 2.), _img); } if(gfx_show_image_bounds) { QRect r(int(layerX() - qreal(_s.width()) / 2.), int(layerY() - qreal(_s.height()) / 2.), _s.width(), _s.height()); p.fillRect(r, QColor(0, 0, 255, 127)); } } p.setOpacity(op); GfxCanvasItem::paint(p); }
QRect GfxCanvasImage::boundingRect() { QMatrix m; m.translate(layerX(), layerY()); m.rotate(_rotate.value()); m.scale(layerScale(), layerScale()); m.translate(-_s.width() / 2, -_s.height() / 2); QRect r(QPoint(0, 0), _s); r = m.mapRect(r); r.setX(r.x() - 1); r.setY(r.y() - 1); r.setWidth(r.width() + 2); r.setHeight(r.height() + 2); return r | GfxCanvasItem::boundingRect();; }
QRect GfxCanvasText::boundingRect() { checkCache(); if(_img.isNull()) return QRect(); QMatrix m; m.translate(layerX(), layerY()); m.scale(layerScale(), layerScale()); m.translate(-_size.width() / 2, -_size.height() / 2); QRect r(getImgPoint(), _img.size()); r = m.mapRect(r); r.setX(r.x() - 1); r.setY(r.y() - 1); r.setWidth(r.width() + 2); r.setHeight(r.height() + 2); return r | GfxCanvasItem::boundingRect();; }
void GfxCanvasColor::paint(GfxPainter &p) { qreal op = p.opacity(); p.setOpacity(op * layerVisible()); QSize s(int(_s.width() * layerScale()), int(_s.height() * layerScale())); if(_rotate.value()) { QMatrix m; m.translate(layerX(), layerY()); m.rotate(_rotate.value()); m.translate(-s.width() / 2, -s.height() / 2); p.fillRectTransformed(m, s, color(), quality().value() != 0.); } else { p.fillRect(QRect(QPoint(int(layerX() - qreal(s.width()) / 2.), int(layerY() - qreal(s.height()) / 2.)), s), color()); } p.setOpacity(op); GfxCanvasItem::paint(p); }
void GfxCanvasMipImage::paint(GfxPainter &p) { if(_imgs.isEmpty() || scale().value() == 0.) return; qreal op = p.opacity(); p.setOpacity(op * layerVisible()); // Find correct image QSize s = layerScale() * _s; int imgNum; for(imgNum = 0; imgNum < _imgs.count(); ++imgNum) if(_imgs.at(imgNum).width() >= s.width()) break; if(imgNum == _imgs.count()) imgNum = _imgs.count() - 1; const QImage &img = _imgs.at(imgNum); // Adjust zoom qreal zoom = qreal(s.width()) / qreal(img.width()); qreal rotate = _rotate.value(); int x = int(layerX()); int y = int(layerY()); if(zoom == 1. && rotate == 0.) { if(subPixelPlacement()) { p.drawImage(qreal(layerX() - qreal(s.width()) / 2.), int(layerY() - qreal(s.height()) / 2.), img); } else { p.drawImage(x - s.width() / 2, y - s.height() / 2, img); } if(gfx_show_mip_matches) { QRect r(x - s.width() / 2, y - s.height() / 2, s.width(), s.height()); p.fillRect(r, QColor(255, 0, 0, 127)); } } else { QMatrix m; m.translate(x, y); if(rotate) m.rotate(rotate); if(zoom != 1.) m.scale(zoom, zoom); m.translate(-img.width() / 2, -img.height() / 2); p.drawImageTransformed(m, img, _quality.value() != 0.); } p.setOpacity(op); GfxCanvasItem::paint(p); }
void TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, const nsIntRegion& aValidRegion, EffectChain& aEffectChain, float aOpacity, const gfx::Point& aOffset, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, const nsIntRegion& aMaskRegion, nsIntRect aVisibleRect, gfx::Matrix4x4 aTransform) { float resolution = aLayerBuffer.GetResolution(); gfxSize layerScale(1, 1); // We assume that the current frame resolution is the one used in our primary // layer buffer. Compensate for a changing frame resolution. if (aLayerBuffer.GetFrameResolution() != mVideoMemoryTiledBuffer.GetFrameResolution()) { const gfxSize& layerResolution = aLayerBuffer.GetFrameResolution(); const gfxSize& localResolution = mVideoMemoryTiledBuffer.GetFrameResolution(); layerScale.width = layerResolution.width / localResolution.width; layerScale.height = layerResolution.height / localResolution.height; aVisibleRect.ScaleRoundOut(layerScale.width, layerScale.height); } aTransform.Scale(1/(resolution * layerScale.width), 1/(resolution * layerScale.height), 1); uint32_t rowCount = 0; uint32_t tileX = 0; for (int32_t x = aVisibleRect.x; x < aVisibleRect.x + aVisibleRect.width;) { rowCount++; int32_t tileStartX = aLayerBuffer.GetTileStart(x); int32_t w = aLayerBuffer.GetScaledTileLength() - tileStartX; if (x + w > aVisibleRect.x + aVisibleRect.width) { w = aVisibleRect.x + aVisibleRect.width - x; } int tileY = 0; for (int32_t y = aVisibleRect.y; y < aVisibleRect.y + aVisibleRect.height;) { int32_t tileStartY = aLayerBuffer.GetTileStart(y); int32_t h = aLayerBuffer.GetScaledTileLength() - tileStartY; if (y + h > aVisibleRect.y + aVisibleRect.height) { h = aVisibleRect.y + aVisibleRect.height - y; } TiledTexture tileTexture = aLayerBuffer. GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x), aLayerBuffer.RoundDownToTileEdge(y))); if (tileTexture != aLayerBuffer.GetPlaceholderTile()) { nsIntRegion tileDrawRegion; tileDrawRegion.And(aValidRegion, nsIntRect(x * layerScale.width, y * layerScale.height, w * layerScale.width, h * layerScale.height)); tileDrawRegion.Sub(tileDrawRegion, aMaskRegion); if (!tileDrawRegion.IsEmpty()) { tileDrawRegion.ScaleRoundOut(resolution / layerScale.width, resolution / layerScale.height); nsIntPoint tileOffset((x - tileStartX) * resolution, (y - tileStartY) * resolution); uint32_t tileSize = aLayerBuffer.GetTileLength(); RenderTile(tileTexture, aEffectChain, aOpacity, aTransform, aOffset, aFilter, aClipRect, tileDrawRegion, tileOffset, nsIntSize(tileSize, tileSize)); } } tileY++; y += h; } tileX++; x += w; } }
void TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, nsIntRegion aVisibleRegion, gfx::Matrix4x4 aTransform) { if (!mCompositor) { NS_WARNING("Can't render tiled content host - no compositor"); return; } float resolution = aLayerBuffer.GetResolution(); gfx::Size layerScale(1, 1); // We assume that the current frame resolution is the one used in our high // precision layer buffer. Compensate for a changing frame resolution when // rendering the low precision buffer. if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) { const CSSToParentLayerScale& layerResolution = aLayerBuffer.GetFrameResolution(); const CSSToParentLayerScale& localResolution = mTiledBuffer.GetFrameResolution(); layerScale.width = layerScale.height = layerResolution.scale / localResolution.scale; aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // If we're drawing the low precision buffer, make sure the high precision // buffer is masked out to avoid overdraw and rendering artifacts with // non-opaque layers. nsIntRegion maskRegion; if (resolution != mTiledBuffer.GetResolution()) { maskRegion = mTiledBuffer.GetValidRegion(); // XXX This should be ScaleRoundIn, but there is no such function on // nsIntRegion. maskRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // Make sure the resolution and difference in frame resolution are accounted // for in the layer transform. aTransform.PreScale(1/(resolution * layerScale.width), 1/(resolution * layerScale.height), 1); uint32_t rowCount = 0; uint32_t tileX = 0; nsIntRect visibleRect = aVisibleRegion.GetBounds(); gfx::IntSize scaledTileSize = aLayerBuffer.GetScaledTileSize(); for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { rowCount++; int32_t tileStartX = aLayerBuffer.GetTileStart(x, scaledTileSize.width); int32_t w = scaledTileSize.width - tileStartX; if (x + w > visibleRect.x + visibleRect.width) { w = visibleRect.x + visibleRect.width - x; } int tileY = 0; for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { int32_t tileStartY = aLayerBuffer.GetTileStart(y, scaledTileSize.height); int32_t h = scaledTileSize.height - tileStartY; if (y + h > visibleRect.y + visibleRect.height) { h = visibleRect.y + visibleRect.height - y; } TileHost tileTexture = aLayerBuffer. GetTile(nsIntPoint(aLayerBuffer.RoundDownToTileEdge(x, scaledTileSize.width), aLayerBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); if (tileTexture != aLayerBuffer.GetPlaceholderTile()) { nsIntRegion tileDrawRegion; tileDrawRegion.And(nsIntRect(x, y, w, h), aLayerBuffer.GetValidRegion()); tileDrawRegion.And(tileDrawRegion, aVisibleRegion); tileDrawRegion.Sub(tileDrawRegion, maskRegion); if (!tileDrawRegion.IsEmpty()) { tileDrawRegion.ScaleRoundOut(resolution, resolution); nsIntPoint tileOffset((x - tileStartX) * resolution, (y - tileStartY) * resolution); gfx::IntSize tileSize = aLayerBuffer.GetTileSize(); RenderTile(tileTexture, aBackgroundColor, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion, tileOffset, nsIntSize(tileSize.width, tileSize.height)); } } tileY++; y += h; } tileX++; x += w; } gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTENT, rect, aClipRect, aTransform, mFlashCounter); }
void TiledContentHost::RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer, const gfxRGBA* aBackgroundColor, EffectChain& aEffectChain, float aOpacity, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, nsIntRegion aVisibleRegion, gfx::Matrix4x4 aTransform) { if (!mCompositor) { NS_WARNING("Can't render tiled content host - no compositor"); return; } float resolution = aLayerBuffer.GetResolution(); gfx::Size layerScale(1, 1); // We assume that the current frame resolution is the one used in our high // precision layer buffer. Compensate for a changing frame resolution when // rendering the low precision buffer. if (aLayerBuffer.GetFrameResolution() != mTiledBuffer.GetFrameResolution()) { const CSSToParentLayerScale2D& layerResolution = aLayerBuffer.GetFrameResolution(); const CSSToParentLayerScale2D& localResolution = mTiledBuffer.GetFrameResolution(); layerScale.width = layerResolution.xScale / localResolution.xScale; layerScale.height = layerResolution.yScale / localResolution.yScale; aVisibleRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // Make sure we don't render at low resolution where we have valid high // resolution content, to avoid overdraw and artifacts with semi-transparent // layers. nsIntRegion maskRegion; if (resolution != mTiledBuffer.GetResolution()) { maskRegion = mTiledBuffer.GetValidRegion(); // XXX This should be ScaleRoundIn, but there is no such function on // nsIntRegion. maskRegion.ScaleRoundOut(layerScale.width, layerScale.height); } // Make sure the resolution and difference in frame resolution are accounted // for in the layer transform. aTransform.PreScale(1/(resolution * layerScale.width), 1/(resolution * layerScale.height), 1); DiagnosticFlags componentAlphaDiagnostic = DiagnosticFlags::NO_DIAGNOSTIC; nsIntRegion compositeRegion = aLayerBuffer.GetValidRegion(); compositeRegion.AndWith(aVisibleRegion); compositeRegion.SubOut(maskRegion); IntRect visibleRect = aVisibleRegion.GetBounds(); if (compositeRegion.IsEmpty()) { return; } if (aBackgroundColor) { nsIntRegion backgroundRegion = compositeRegion; backgroundRegion.ScaleRoundOut(resolution, resolution); EffectChain effect; effect.mPrimaryEffect = new EffectSolidColor(ToColor(*aBackgroundColor)); nsIntRegionRectIterator it(backgroundRegion); for (const IntRect* rect = it.Next(); rect != nullptr; rect = it.Next()) { Rect graphicsRect(rect->x, rect->y, rect->width, rect->height); mCompositor->DrawQuad(graphicsRect, aClipRect, effect, 1.0, aTransform); } } for (size_t i = 0; i < aLayerBuffer.GetTileCount(); ++i) { TileHost& tile = aLayerBuffer.GetTile(i); if (tile.IsPlaceholderTile()) { continue; } TileIntPoint tilePosition = aLayerBuffer.GetPlacement().TilePosition(i); // A sanity check that catches a lot of mistakes. MOZ_ASSERT(tilePosition.x == tile.mTilePosition.x && tilePosition.y == tile.mTilePosition.y); IntPoint tileOffset = aLayerBuffer.GetTileOffset(tilePosition); nsIntRegion tileDrawRegion = IntRect(tileOffset, aLayerBuffer.GetScaledTileSize()); tileDrawRegion.AndWith(compositeRegion); if (tileDrawRegion.IsEmpty()) { continue; } tileDrawRegion.ScaleRoundOut(resolution, resolution); RenderTile(tile, aEffectChain, aOpacity, aTransform, aFilter, aClipRect, tileDrawRegion, tileOffset * resolution, aLayerBuffer.GetTileSize(), gfx::Rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height)); if (tile.mTextureHostOnWhite) { componentAlphaDiagnostic = DiagnosticFlags::COMPONENT_ALPHA; } } gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); GetCompositor()->DrawDiagnostics(DiagnosticFlags::CONTENT | componentAlphaDiagnostic, rect, aClipRect, aTransform, mFlashCounter); }