mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 746896. Fix a bug with printing Azure canvas. r=joe
This commit is contained in:
parent
64edc63a64
commit
997a3716ac
@ -2,6 +2,9 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_2D_GLUE_H
|
||||
#define GFX_2D_GLUE_H
|
||||
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxRect.h"
|
||||
@ -177,6 +180,22 @@ inline gfxMatrix ThebesMatrix(const Matrix &aMatrix)
|
||||
aMatrix._22, aMatrix._31, aMatrix._32);
|
||||
}
|
||||
|
||||
inline gfxASurface::gfxImageFormat SurfaceFormatToImageFormat(SurfaceFormat aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
case FORMAT_B8G8R8A8:
|
||||
return gfxASurface::ImageFormatARGB32;
|
||||
case FORMAT_B8G8R8X8:
|
||||
return gfxASurface::ImageFormatRGB24;
|
||||
case FORMAT_R5G6B5:
|
||||
return gfxASurface::ImageFormatRGB16_565;
|
||||
case FORMAT_A8:
|
||||
return gfxASurface::ImageFormatA8;
|
||||
default:
|
||||
return gfxASurface::ImageFormatUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
inline gfxASurface::gfxContentType ContentForFormat(const SurfaceFormat &aFormat)
|
||||
{
|
||||
switch (aFormat) {
|
||||
@ -245,3 +264,5 @@ inline gfxContext::GraphicsOperator ThebesOp(CompositionOp aOp)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
gfxImageSurface::gfxImageSurface()
|
||||
: mSize(0, 0),
|
||||
@ -171,32 +175,75 @@ gfxImageSurface::ComputeStride(const gfxIntSize& aSize, gfxImageFormat aFormat)
|
||||
return stride;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxImageSurface::CopyFrom(gfxImageSurface *other)
|
||||
// helper function for the CopyFrom methods
|
||||
static void
|
||||
CopyForStride(unsigned char* aDest, unsigned char* aSrc, const gfxIntSize& aSize, long aDestStride, long aSrcStride)
|
||||
{
|
||||
if (other->mSize != mSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other->mFormat != mFormat &&
|
||||
!(other->mFormat == ImageFormatARGB32 && mFormat == ImageFormatRGB24) &&
|
||||
!(other->mFormat == ImageFormatRGB24 && mFormat == ImageFormatARGB32))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (other->mStride == mStride) {
|
||||
memcpy (mData, other->mData, mStride * mSize.height);
|
||||
if (aDestStride == aSrcStride) {
|
||||
memcpy (aDest, aSrc, aSrcStride * aSize.height);
|
||||
} else {
|
||||
int lineSize = NS_MIN(other->mStride, mStride);
|
||||
for (int i = 0; i < mSize.height; i++) {
|
||||
unsigned char *src = other->mData + other->mStride * i;
|
||||
unsigned char *dst = mData + mStride * i;
|
||||
int lineSize = NS_MIN(aDestStride, aSrcStride);
|
||||
for (int i = 0; i < aSize.height; i++) {
|
||||
unsigned char* src = aSrc + aSrcStride * i;
|
||||
unsigned char* dst = aDest + aDestStride * i;
|
||||
|
||||
memcpy (dst, src, lineSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// helper function for the CopyFrom methods
|
||||
static bool
|
||||
FormatsAreCompatible(gfxASurface::gfxImageFormat a1, gfxASurface::gfxImageFormat a2)
|
||||
{
|
||||
if (a1 != a2 &&
|
||||
!(a1 == gfxASurface::ImageFormatARGB32 &&
|
||||
a2 == gfxASurface::ImageFormatRGB24) &&
|
||||
!(a1 == gfxASurface::ImageFormatRGB24 &&
|
||||
a2 == gfxASurface::ImageFormatARGB32)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxImageSurface::CopyFrom (SourceSurface *aSurface)
|
||||
{
|
||||
mozilla::RefPtr<DataSourceSurface> data = aSurface->GetDataSurface();
|
||||
|
||||
if (!data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gfxIntSize size(data->GetSize().width, data->GetSize().height);
|
||||
if (size != mSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FormatsAreCompatible(SurfaceFormatToImageFormat(aSurface->GetFormat()),
|
||||
mFormat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyForStride(mData, data->GetData(), size, mStride, data->Stride());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
gfxImageSurface::CopyFrom(gfxImageSurface *other)
|
||||
{
|
||||
if (other->mSize != mSize) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!FormatsAreCompatible(other->mFormat, mFormat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CopyForStride(mData, other->mData, mSize, mStride, other->mStride);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -13,6 +13,12 @@
|
||||
|
||||
class gfxSubimageSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurface;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A raw image buffer. The format can be set in the constructor. Its main
|
||||
* purpose is for storing read-only images and using it as a source surface,
|
||||
@ -69,6 +75,12 @@ public:
|
||||
/* Fast copy from another image surface; returns TRUE if successful, FALSE otherwise */
|
||||
bool CopyFrom (gfxImageSurface *other);
|
||||
|
||||
/**
|
||||
* Fast copy from a source surface; returns TRUE if successful, FALSE otherwise
|
||||
* Assumes that the format of this surface is compatable with aSurface
|
||||
*/
|
||||
bool CopyFrom (mozilla::gfx::SourceSurface *aSurface);
|
||||
|
||||
/* return new Subimage with pointing to original image starting from aRect.pos
|
||||
* and size of aRect.size. New subimage keeping current image reference
|
||||
*/
|
||||
|
@ -559,13 +559,6 @@ gfxPlatform::GetScaledFontForFont(gfxFont *aFont)
|
||||
return scaledFont;
|
||||
}
|
||||
|
||||
cairo_user_data_key_t kDrawSourceSurface;
|
||||
static void
|
||||
DataSourceSurfaceDestroy(void *dataSourceSurface)
|
||||
{
|
||||
static_cast<DataSourceSurface*>(dataSourceSurface)->Release();
|
||||
}
|
||||
|
||||
UserDataKey kThebesSurfaceKey;
|
||||
void
|
||||
DestroyThebesSurface(void *data)
|
||||
@ -605,11 +598,12 @@ gfxPlatform::GetThebesSurfaceForDrawTarget(DrawTarget *aTarget)
|
||||
IntSize size = data->GetSize();
|
||||
gfxASurface::gfxImageFormat format = OptimalFormatForContent(ContentForFormat(data->GetFormat()));
|
||||
|
||||
surf =
|
||||
new gfxImageSurface(data->GetData(), gfxIntSize(size.width, size.height),
|
||||
data->Stride(), format);
|
||||
|
||||
surf->SetData(&kDrawSourceSurface, data.forget().drop(), DataSourceSurfaceDestroy);
|
||||
// We need to make a copy here because data might change its data under us
|
||||
nsRefPtr<gfxImageSurface> imageSurf = new gfxImageSurface(gfxIntSize(size.width, size.height), format, false);
|
||||
|
||||
bool resultOfCopy = imageSurf->CopyFrom(source);
|
||||
NS_ASSERTION(resultOfCopy, "Failed to copy surface.");
|
||||
surf = imageSurf;
|
||||
}
|
||||
|
||||
// add a reference to be held by the drawTarget
|
||||
|
Loading…
Reference in New Issue
Block a user