зеркало из https://github.com/mozilla/gecko-dev.git
b=294400, fix mac image handling; 293221, default canvas values; 294572, mac image rendering issues. r+a=shaver
This commit is contained in:
Родитель
87f0855b0e
Коммит
72b760f1ad
|
@ -204,6 +204,7 @@ protected:
|
||||||
enum {
|
enum {
|
||||||
STYLE_STROKE = 0,
|
STYLE_STROKE = 0,
|
||||||
STYLE_FILL,
|
STYLE_FILL,
|
||||||
|
STYLE_SHADOW,
|
||||||
STYLE_MAX
|
STYLE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,7 +286,8 @@ nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||||
mDirty(PR_TRUE), mCairo(nsnull), mSurface(nsnull), mSurfaceData(nsnull)
|
mDirty(PR_TRUE), mCairo(nsnull), mSurface(nsnull), mSurfaceData(nsnull)
|
||||||
{
|
{
|
||||||
mColorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
|
mColorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
|
||||||
mColorStyles[STYLE_FILL] = NS_RGB(255,255,255);
|
mColorStyles[STYLE_FILL] = NS_RGB(0,0,0);
|
||||||
|
mColorStyles[STYLE_SHADOW] = NS_RGBA(0,0,0,0);
|
||||||
|
|
||||||
mLastStyle = (PRInt32) -1;
|
mLastStyle = (PRInt32) -1;
|
||||||
|
|
||||||
|
@ -506,6 +508,13 @@ nsCanvasRenderingContext2D::SetTargetImageFrame(gfxIImageFrame* aImageFrame)
|
||||||
mWidth * 4);
|
mWidth * 4);
|
||||||
cairo_set_target_surface (mCairo, mSurface);
|
cairo_set_target_surface (mCairo, mSurface);
|
||||||
|
|
||||||
|
// set up the initial canvas defaults
|
||||||
|
cairo_set_line_width (mCairo, 1.0);
|
||||||
|
cairo_set_operator (mCairo, CAIRO_OPERATOR_OVER);
|
||||||
|
cairo_set_miter_limit(mCairo, 10.0);
|
||||||
|
cairo_set_line_cap(mCairo, CAIRO_LINE_CAP_BUTT);
|
||||||
|
cairo_set_line_join(mCairo, CAIRO_LINE_JOIN_MITER);
|
||||||
|
|
||||||
mImageFrame = aImageFrame;
|
mImageFrame = aImageFrame;
|
||||||
|
|
||||||
return ClearRect (0, 0, mWidth, mHeight);
|
return ClearRect (0, 0, mWidth, mHeight);
|
||||||
|
@ -548,22 +557,33 @@ nsCanvasRenderingContext2D::UpdateImageFrame()
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
||||||
|
PRBool topToBottom = img->GetIsRowOrderTopToBottom();
|
||||||
|
|
||||||
for (PRUint32 j = 0; j < (PRUint32) mHeight; j++) {
|
for (PRUint32 j = 0; j < (PRUint32) mHeight; j++) {
|
||||||
PRUint8 *inrow = (PRUint8*)(mSurfaceData + (mWidth * 4 * j));
|
PRUint8 *inrow = (PRUint8*)(mSurfaceData + (mWidth * 4 * j));
|
||||||
#ifdef XP_WIN
|
|
||||||
// On windows, RGB_A8 is really "BGR with Y axis flipped"
|
PRUint32 rowIndex;
|
||||||
PRUint8 *outrowrgb = rgbBits + (rgbStride * (mHeight - j - 1));
|
if (topToBottom)
|
||||||
PRUint8 *outrowalpha = alphaBits + (alphaStride * (mHeight - j - 1));
|
rowIndex = j;
|
||||||
#else
|
else
|
||||||
PRUint8 *outrowrgb = rgbBits + (rgbStride * j);
|
rowIndex = mHeight - j - 1;
|
||||||
PRUint8 *outrowalpha = alphaBits + (alphaStride * j);
|
|
||||||
#endif
|
PRUint8 *outrowrgb = rgbBits + (rgbStride * rowIndex);
|
||||||
|
PRUint8 *outrowalpha = alphaBits + (alphaStride * rowIndex);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) mWidth; i++) {
|
for (PRUint32 i = 0; i < (PRUint32) mWidth; i++) {
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
PRUint8 b = *inrow++;
|
PRUint8 b = *inrow++;
|
||||||
PRUint8 g = *inrow++;
|
PRUint8 g = *inrow++;
|
||||||
PRUint8 r = *inrow++;
|
PRUint8 r = *inrow++;
|
||||||
PRUint8 a = *inrow++;
|
PRUint8 a = *inrow++;
|
||||||
|
#else
|
||||||
|
PRUint8 a = *inrow++;
|
||||||
|
PRUint8 r = *inrow++;
|
||||||
|
PRUint8 g = *inrow++;
|
||||||
|
PRUint8 b = *inrow++;
|
||||||
|
#endif
|
||||||
// now recover the real bgra from the cairo
|
// now recover the real bgra from the cairo
|
||||||
// premultiplied values
|
// premultiplied values
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
|
@ -603,7 +623,6 @@ nsCanvasRenderingContext2D::UpdateImageFrame()
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
nsCOMPtr<nsIImage> img(do_GetInterface(mImageFrame));
|
|
||||||
nsRect r(0, 0, mWidth, mHeight);
|
nsRect r(0, 0, mWidth, mHeight);
|
||||||
img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
img->ImageUpdated(nsnull, nsImageUpdateFlags_kBitsChanged, &r);
|
||||||
|
|
||||||
|
@ -909,6 +928,7 @@ nsCanvasRenderingContext2D::SetShadowColor(const nsAString& color)
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsCanvasRenderingContext2D::GetShadowColor(nsAString& color)
|
nsCanvasRenderingContext2D::GetShadowColor(nsAString& color)
|
||||||
{
|
{
|
||||||
|
StyleColorToString(mColorStyles[STYLE_SHADOW], color);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1074,7 +1094,9 @@ nsCanvasRenderingContext2D::SetLineCap(const nsAString& capstyle)
|
||||||
{
|
{
|
||||||
cairo_line_cap_t cap;
|
cairo_line_cap_t cap;
|
||||||
|
|
||||||
if (capstyle.EqualsLiteral("round"))
|
if (capstyle.EqualsLiteral("butt"))
|
||||||
|
cap = CAIRO_LINE_CAP_BUTT;
|
||||||
|
else if (capstyle.EqualsLiteral("round"))
|
||||||
cap = CAIRO_LINE_CAP_ROUND;
|
cap = CAIRO_LINE_CAP_ROUND;
|
||||||
else if (capstyle.EqualsLiteral("square"))
|
else if (capstyle.EqualsLiteral("square"))
|
||||||
cap = CAIRO_LINE_CAP_SQUARE;
|
cap = CAIRO_LINE_CAP_SQUARE;
|
||||||
|
@ -1090,7 +1112,9 @@ nsCanvasRenderingContext2D::GetLineCap(nsAString& capstyle)
|
||||||
{
|
{
|
||||||
cairo_line_cap_t cap = cairo_current_line_cap(mCairo);
|
cairo_line_cap_t cap = cairo_current_line_cap(mCairo);
|
||||||
|
|
||||||
if (cap == CAIRO_LINE_CAP_ROUND)
|
if (cap == CAIRO_LINE_CAP_BUTT)
|
||||||
|
capstyle.AssignLiteral("butt");
|
||||||
|
else if (cap == CAIRO_LINE_CAP_ROUND)
|
||||||
capstyle.AssignLiteral("round");
|
capstyle.AssignLiteral("round");
|
||||||
else if (cap == CAIRO_LINE_CAP_SQUARE)
|
else if (cap == CAIRO_LINE_CAP_SQUARE)
|
||||||
capstyle.AssignLiteral("square");
|
capstyle.AssignLiteral("square");
|
||||||
|
@ -1272,18 +1296,22 @@ nsCanvasRenderingContext2D::SetGlobalCompositeOperation(const nsAString& op)
|
||||||
if (op.EqualsLiteral(cvsop)) \
|
if (op.EqualsLiteral(cvsop)) \
|
||||||
cairo_op = CAIRO_OPERATOR_##cairoop;
|
cairo_op = CAIRO_OPERATOR_##cairoop;
|
||||||
|
|
||||||
|
// XXX Need to confirm if these are the right ops;
|
||||||
|
// will be irrelevant once we switch to CVS cairo,
|
||||||
|
// because the operators there have names that exactly
|
||||||
|
// match the canvas ops.
|
||||||
CANVAS_OP_TO_CAIRO_OP("clear", CLEAR)
|
CANVAS_OP_TO_CAIRO_OP("clear", CLEAR)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("copy", SRC)
|
else CANVAS_OP_TO_CAIRO_OP("copy", SRC)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("darker", SATURATE) // XXX
|
else CANVAS_OP_TO_CAIRO_OP("darker", SATURATE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-atop", ATOP_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-atop", ATOP_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-in", IN_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-in", IN_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-out", OUT_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-out", OUT_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-over", OVER_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-over", OVER_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("lighter", SATURATE)
|
else CANVAS_OP_TO_CAIRO_OP("lighter", ADD)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-atop", ATOP)
|
else CANVAS_OP_TO_CAIRO_OP("source-atop", ATOP)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-in", IN)
|
else CANVAS_OP_TO_CAIRO_OP("source-in", IN)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-out", OUT)
|
else CANVAS_OP_TO_CAIRO_OP("source-out", OUT)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-over", OVER)
|
else CANVAS_OP_TO_CAIRO_OP("source-over", SRC)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("xor", XOR)
|
else CANVAS_OP_TO_CAIRO_OP("xor", XOR)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("over", OVER)
|
else CANVAS_OP_TO_CAIRO_OP("over", OVER)
|
||||||
else return NS_ERROR_NOT_IMPLEMENTED;
|
else return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
@ -1303,18 +1331,22 @@ nsCanvasRenderingContext2D::GetGlobalCompositeOperation(nsAString& op)
|
||||||
if (cairo_op == CAIRO_OPERATOR_##cairoop) \
|
if (cairo_op == CAIRO_OPERATOR_##cairoop) \
|
||||||
op.AssignLiteral(cvsop);
|
op.AssignLiteral(cvsop);
|
||||||
|
|
||||||
|
// XXX Need to confirm if these are the right ops;
|
||||||
|
// will be irrelevant once we switch to CVS cairo,
|
||||||
|
// because the operators there have names that exactly
|
||||||
|
// match the canvas ops.
|
||||||
CANVAS_OP_TO_CAIRO_OP("clear", CLEAR)
|
CANVAS_OP_TO_CAIRO_OP("clear", CLEAR)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("copy", SRC)
|
else CANVAS_OP_TO_CAIRO_OP("copy", SRC)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("darker", SATURATE) // XXX
|
else CANVAS_OP_TO_CAIRO_OP("darker", SATURATE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-atop", ATOP_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-atop", ATOP_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-in", IN_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-in", IN_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-out", OUT_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-out", OUT_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("destination-over", OVER_REVERSE)
|
else CANVAS_OP_TO_CAIRO_OP("destination-over", OVER_REVERSE)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("lighter", SATURATE)
|
else CANVAS_OP_TO_CAIRO_OP("lighter", ADD)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-atop", ATOP)
|
else CANVAS_OP_TO_CAIRO_OP("source-atop", ATOP)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-in", IN)
|
else CANVAS_OP_TO_CAIRO_OP("source-in", IN)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-out", OUT)
|
else CANVAS_OP_TO_CAIRO_OP("source-out", OUT)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("source-over", OVER)
|
else CANVAS_OP_TO_CAIRO_OP("source-over", SRC)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("xor", XOR)
|
else CANVAS_OP_TO_CAIRO_OP("xor", XOR)
|
||||||
else CANVAS_OP_TO_CAIRO_OP("over", OVER)
|
else CANVAS_OP_TO_CAIRO_OP("over", OVER)
|
||||||
else return NS_ERROR_FAILURE;
|
else return NS_ERROR_FAILURE;
|
||||||
|
@ -1380,6 +1412,11 @@ nsCanvasRenderingContext2D::ConvertJSValToXPCObject(nsISupports** aSupports, REF
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cairo ARGB32 surfaces are ARGB stored as a packed 32-bit integer; on little-endian
|
||||||
|
* platforms, they appear as BGRA bytes in the surface data. The color values are also
|
||||||
|
* stored with premultiplied alpha.
|
||||||
|
*/
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement *imgElt,
|
nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement *imgElt,
|
||||||
cairo_surface_t **aCairoSurface,
|
cairo_surface_t **aCairoSurface,
|
||||||
|
@ -1456,14 +1493,18 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
if (format == gfxIFormats::RGB || format == gfxIFormats::BGR) {
|
if (format == gfxIFormats::RGB || format == gfxIFormats::BGR) {
|
||||||
useBGR = (format & 1);
|
useBGR = (format & 1);
|
||||||
|
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
#ifdef IS_BIG_ENDIAN
|
||||||
PRUint8 *inrowrgb;
|
useBGR = !useBGR;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (topToBottom) {
|
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
||||||
inrowrgb = inPixBits + (inPixStride * j);
|
PRUint32 rowIndex;
|
||||||
} else {
|
if (topToBottom)
|
||||||
inrowrgb = inPixBits + (inPixStride * (imgHeight - j - 1));
|
rowIndex = j;
|
||||||
}
|
else
|
||||||
|
rowIndex = imgHeight - j - 1;
|
||||||
|
|
||||||
|
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
||||||
// handle rgb data; no alpha to premultiply
|
// handle rgb data; no alpha to premultiply
|
||||||
|
@ -1475,6 +1516,11 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
PRUint8 g = *inrowrgb++;
|
PRUint8 g = *inrowrgb++;
|
||||||
PRUint8 r = *inrowrgb++;
|
PRUint8 r = *inrowrgb++;
|
||||||
|
|
||||||
|
#ifdef IS_BIG_ENDIAN
|
||||||
|
// alpha
|
||||||
|
*outData++ = 0xff;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (useBGR) {
|
if (useBGR) {
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
*outData++ = g;
|
*outData++ = g;
|
||||||
|
@ -1485,24 +1531,29 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
// alpha
|
// alpha
|
||||||
*outData++ = 255;
|
*outData++ = 0xff;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
} else if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
|
} else if (format == gfxIFormats::RGB_A1 || format == gfxIFormats::BGR_A1) {
|
||||||
useBGR = (format & 1);
|
useBGR = (format & 1);
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
|
||||||
PRUint8 *inrowrgb;
|
|
||||||
PRUint8 *inrowalpha;
|
|
||||||
|
|
||||||
if (topToBottom) {
|
#ifdef IS_BIG_ENDIAN
|
||||||
inrowrgb = inPixBits + (inPixStride * j);
|
useBGR = !useBGR;
|
||||||
inrowalpha = inAlphaBits + (inAlphaStride * j);
|
#endif
|
||||||
} else {
|
|
||||||
inrowrgb = inPixBits + (inPixStride * (imgHeight - j - 1));
|
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
||||||
inrowalpha = inAlphaBits + (inAlphaStride * (imgHeight - j - 1));
|
PRUint32 rowIndex;
|
||||||
}
|
if (topToBottom)
|
||||||
|
rowIndex = j;
|
||||||
|
else
|
||||||
|
rowIndex = imgHeight - j - 1;
|
||||||
|
|
||||||
|
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
||||||
|
PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
||||||
// pull out alpha to premultiply
|
// pull out alpha to premultiply
|
||||||
|
@ -1512,8 +1563,8 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
PRUint8 a = (inrowalpha[byte] >> bit) & 1;
|
PRUint8 a = (inrowalpha[byte] >> bit) & 1;
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
// skip extra X8 byte on OSX
|
// skip extra X8 byte on OSX
|
||||||
inrowrgb++;
|
inrowrgb++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// handle rgb data; need to multiply the alpha out,
|
// handle rgb data; need to multiply the alpha out,
|
||||||
|
@ -1524,6 +1575,11 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
PRUint8 g = *inrowrgb++;
|
PRUint8 g = *inrowrgb++;
|
||||||
PRUint8 r = *inrowrgb++;
|
PRUint8 r = *inrowrgb++;
|
||||||
|
|
||||||
|
#ifdef IS_BIG_ENDIAN
|
||||||
|
// alpha
|
||||||
|
*outData++ = 0xff;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (useBGR) {
|
if (useBGR) {
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
*outData++ = g;
|
*outData++ = g;
|
||||||
|
@ -1534,7 +1590,10 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
// alpha
|
||||||
*outData++ = 0xff;
|
*outData++ = 0xff;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
// alpha is 0, so we need to write all 0's,
|
// alpha is 0, so we need to write all 0's,
|
||||||
// ignoring input color
|
// ignoring input color
|
||||||
|
@ -1549,17 +1608,20 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
} else if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
|
} else if (format == gfxIFormats::RGB_A8 || format == gfxIFormats::BGR_A8) {
|
||||||
useBGR = (format & 1);
|
useBGR = (format & 1);
|
||||||
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
|
||||||
PRUint8 *inrowrgb;
|
|
||||||
PRUint8 *inrowalpha;
|
|
||||||
|
|
||||||
if (topToBottom) {
|
#ifdef IS_BIG_ENDIAN
|
||||||
inrowrgb = inPixBits + (inPixStride * j);
|
useBGR = !useBGR;
|
||||||
inrowalpha = inAlphaBits + (inAlphaStride * j);
|
#endif
|
||||||
} else {
|
|
||||||
inrowrgb = inPixBits + (inPixStride * (imgHeight - j - 1));
|
for (PRUint32 j = 0; j < (PRUint32) imgHeight; j++) {
|
||||||
inrowalpha = inAlphaBits + (inAlphaStride * (imgHeight - j - 1));
|
PRUint32 rowIndex;
|
||||||
}
|
if (topToBottom)
|
||||||
|
rowIndex = j;
|
||||||
|
else
|
||||||
|
rowIndex = imgHeight - j - 1;
|
||||||
|
|
||||||
|
PRUint8 *inrowrgb = inPixBits + (inPixStride * rowIndex);
|
||||||
|
PRUint8 *inrowalpha = inAlphaBits + (inAlphaStride * rowIndex);
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
for (PRUint32 i = 0; i < (PRUint32) imgWidth; i++) {
|
||||||
// pull out alpha; we'll need it to premultiply
|
// pull out alpha; we'll need it to premultiply
|
||||||
|
@ -1571,10 +1633,31 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
// skip extra X8 byte on OSX
|
// skip extra X8 byte on OSX
|
||||||
inrowrgb++;
|
inrowrgb++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// XXX gcc bug: gcc seems to push "r" into a register
|
||||||
|
// early, and pretends that it's in that register
|
||||||
|
// throughout the 3 macros below. At the end
|
||||||
|
// of the 3rd macro, the correct r value is
|
||||||
|
// calculated but never stored anywhere -- the r variable
|
||||||
|
// has the value of the low byte of register that it
|
||||||
|
// was stuffed into, which has the result of some
|
||||||
|
// intermediate calculation.
|
||||||
|
// I've seen this on gcc 3.4.2 x86 (Fedora Core 3)
|
||||||
|
// and gcc 3.3 PPC (OS X 10.3)
|
||||||
|
|
||||||
|
//PRUint8 b, g, r;
|
||||||
|
//FAST_DIVIDE_BY_255(b, *inrowrgb++ * a - a / 2);
|
||||||
|
//FAST_DIVIDE_BY_255(g, *inrowrgb++ * a - a / 2);
|
||||||
|
//FAST_DIVIDE_BY_255(r, *inrowrgb++ * a - a / 2);
|
||||||
|
|
||||||
PRUint8 b = (*inrowrgb++ * a - a / 2) / 255;
|
PRUint8 b = (*inrowrgb++ * a - a / 2) / 255;
|
||||||
PRUint8 g = (*inrowrgb++ * a - a / 2) / 255;
|
PRUint8 g = (*inrowrgb++ * a - a / 2) / 255;
|
||||||
PRUint8 r = (*inrowrgb++ * a - a / 2) / 255;
|
PRUint8 r = (*inrowrgb++ * a - a / 2) / 255;
|
||||||
|
|
||||||
|
#ifdef IS_BIG_ENDIAN
|
||||||
|
*outData++ = a;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (useBGR) {
|
if (useBGR) {
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
*outData++ = g;
|
*outData++ = g;
|
||||||
|
@ -1584,7 +1667,10 @@ nsCanvasRenderingContext2D::CairoSurfaceFromImageElement(nsIDOMHTMLImageElement
|
||||||
*outData++ = g;
|
*outData++ = g;
|
||||||
*outData++ = b;
|
*outData++ = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
*outData++ = a;
|
*outData++ = a;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rv = NS_OK;
|
rv = NS_OK;
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
virtual nsresult Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth, nsMaskRequirements aMaskRequirements);
|
||||||
virtual PRInt32 GetBytesPix() { return mBytesPerPixel; } // this is unused
|
virtual PRInt32 GetBytesPix() { return mBytesPerPixel; } // this is unused
|
||||||
virtual PRBool GetIsRowOrderTopToBottom() { return PR_TRUE; }
|
virtual PRBool GetIsRowOrderTopToBottom() { return PR_FALSE; }
|
||||||
|
|
||||||
virtual PRInt32 GetWidth() { return mWidth; }
|
virtual PRInt32 GetWidth() { return mWidth; }
|
||||||
virtual PRInt32 GetHeight() { return mHeight; }
|
virtual PRInt32 GetHeight() { return mHeight; }
|
||||||
|
|
Загрузка…
Ссылка в новой задаче