зеркало из https://github.com/mozilla/gecko-dev.git
Bug 225243 - postscript output inverted in xft build configuration.
Patch by kherron, r=tor, sr=bzbarsky, a=dbaron
This commit is contained in:
Родитель
dd11ab57c2
Коммит
dbb502dbeb
|
@ -617,16 +617,13 @@ FILE *f;
|
|||
|
||||
fprintf(f, "] /isolatin1encoding exch def\n");
|
||||
|
||||
// Procedure to reencode and invert a font
|
||||
// Procedure to reencode a font
|
||||
fprintf(f, "%s",
|
||||
"/Mfr {\n"
|
||||
" findfont dup length dict\n"
|
||||
" begin\n"
|
||||
" {1 index /FID ne {def} {pop pop} ifelse} forall\n"
|
||||
" /Encoding isolatin1encoding def\n"
|
||||
// Generate a new fontmatrix with the Y scale inverted
|
||||
" 1 -1 matrix scale /FontMatrix load\n"
|
||||
" matrix concatmatrix /FontMatrix exch def\n"
|
||||
" currentdict\n"
|
||||
" end\n"
|
||||
" definefont pop\n"
|
||||
|
@ -1975,18 +1972,19 @@ FILE *f;
|
|||
mPrintSetup->num_copies);
|
||||
}
|
||||
fprintf(f,"/pagelevel save def\n");
|
||||
// Rescale the coordinate system from points to twips, with the Y
|
||||
// axis increasing downwards.
|
||||
fprintf(f, "%g -%g scale\n",
|
||||
// Rescale the coordinate system from points to twips.
|
||||
fprintf(f, "%g %g scale\n",
|
||||
1.0 / TWIPS_PER_POINT_FLOAT, 1.0 / TWIPS_PER_POINT_FLOAT);
|
||||
// Move the origin to the top left of the printable area.
|
||||
// Move the origin to the bottom left of the printable region.
|
||||
if (mPrintContext->prSetup->landscape){
|
||||
fprintf(f, "-90 rotate %d %d translate\n",
|
||||
mPrintContext->prSetup->left, mPrintContext->prSetup->top);
|
||||
fprintf(f, "90 rotate %d -%d translate\n",
|
||||
mPrintContext->prSetup->left,
|
||||
mPrintContext->prSetup->height + mPrintContext->prSetup->top);
|
||||
}
|
||||
else {
|
||||
fprintf(f, "%d -%d translate\n", mPrintContext->prSetup->left,
|
||||
mPrintContext->prSetup->bottom + mPrintContext->prSetup->height);
|
||||
fprintf(f, "%d %d translate\n",
|
||||
mPrintContext->prSetup->left,
|
||||
mPrintContext->prSetup->bottom);
|
||||
}
|
||||
// Try to turn on automatic stroke adjust
|
||||
fputs("true Msetstrokeadjust\n", f);
|
||||
|
@ -2517,178 +2515,133 @@ nsPostScriptObj::translate(nscoord x, nscoord y)
|
|||
}
|
||||
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsPostScriptObj.h
|
||||
* Special notes, this on window will blow up since we can not get the bits in a DDB
|
||||
* @update 2/1/99 dwc
|
||||
*/
|
||||
void
|
||||
nsPostScriptObj::grayimage(
|
||||
nsIImage *aImage, const nsRect& sRect, const nsRect& dRect)
|
||||
{
|
||||
PRInt32 rowData, x, y;
|
||||
PRInt32 width, height, bytewidth, cbits, n;
|
||||
PRUint8 *theBits, *curline;
|
||||
PRBool isTopToBottom;
|
||||
PRInt32 sRow, eRow, rStep;
|
||||
/** ---------------------------------------------------
|
||||
* Draw an image. dRect may be thought of as a hole in the document
|
||||
* page, through which we can see another page containing the image.
|
||||
* sRect is the portion of the image page which is visible through the
|
||||
* hole in the document. iRect is the portion of the image page which
|
||||
* contains the image represented by anImage. sRect and iRect may be
|
||||
* at arbitrary positions relative to each other.
|
||||
*
|
||||
* @update 11/25/2003 kherron
|
||||
* @param anImage Image to draw
|
||||
* @param dRect Rectangle describing where on the page the image
|
||||
* should appear. Units are twips.
|
||||
* @param sRect Rectangle describing the portion of the image that
|
||||
* appears on the page, i.e. the part of the image's
|
||||
* coordinate space that maps to dRect.
|
||||
* @param iRect Rectangle describing the portion of the image's
|
||||
* coordinate space covered by the image pixel data.
|
||||
*/
|
||||
|
||||
// No point in scaling images to 0--some printers choke on it (bug 191684)
|
||||
if (dRect.width == 0 || dRect.height == 0) {
|
||||
void
|
||||
nsPostScriptObj::draw_image(nsIImage *anImage,
|
||||
const nsRect& sRect, const nsRect& iRect, const nsRect& dRect)
|
||||
{
|
||||
FILE *f = mPrintContext->prSetup->tmpBody;
|
||||
|
||||
// If a final image dimension is 0 pixels, just return (see bug 191684)
|
||||
if ((0 == dRect.width) || (0 == dRect.height)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aImage->LockImagePixels(PR_FALSE);
|
||||
theBits = aImage->GetBits();
|
||||
anImage->LockImagePixels(PR_FALSE);
|
||||
PRUint8 *theBits = anImage->GetBits();
|
||||
|
||||
/* image data might not be available (ex: spacer image) */
|
||||
if (!theBits)
|
||||
{
|
||||
aImage->UnlockImagePixels(PR_FALSE);
|
||||
anImage->UnlockImagePixels(PR_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
rowData = aImage->GetLineStride();
|
||||
height = aImage->GetHeight();
|
||||
width = aImage->GetWidth();
|
||||
bytewidth = 3 * sRect.width;
|
||||
cbits = 8;
|
||||
// Save the current graphic state and define a PS variable that
|
||||
// can hold one line of pixel data.
|
||||
fprintf(f, "gsave\n/rowdata %d string def\n",
|
||||
mPrintSetup->color ? iRect.width * 3 : iRect.width);
|
||||
|
||||
// Translate the coordinate origin to the corner of the rectangle where
|
||||
// the image should appear, set up a clipping region, and scale the
|
||||
// coordinate system to the image's final size.
|
||||
translate(dRect.x, dRect.y);
|
||||
box(0, 0, dRect.width, dRect.height);
|
||||
clip();
|
||||
fprintf(f, "%d %d scale\n", dRect.width, dRect.height);
|
||||
|
||||
XL_SET_NUMERIC_LOCALE();
|
||||
// Describe how the pixel data is to be interpreted: pixels per row,
|
||||
// rows, and bits per pixel (per component in color).
|
||||
fprintf(f, "%d %d 8 ", iRect.width, iRect.height);
|
||||
|
||||
FILE *f = mPrintContext->prSetup->tmpBody;
|
||||
fprintf(f, "gsave\n");
|
||||
fprintf(f, "/rowdata %d string def\n", bytewidth/3);
|
||||
// Translate to the lower left corner of the image
|
||||
translate(dRect.x, dRect.y + dRect.height);
|
||||
// Set the image scale, keeping in mind the Y axis is inverted
|
||||
fprintf(f, "%d %d scale\n", dRect.width, -dRect.height);
|
||||
fprintf(f, "%d %d %d ", sRect.width, sRect.height, cbits);
|
||||
fprintf(f, "[ %d 0 0 %d 0 0 ]\n", sRect.width, sRect.height);
|
||||
fprintf(f, " { currentfile rowdata readhexstring pop }\n");
|
||||
fprintf(f, " image\n");
|
||||
// Output the transformation matrix for the image. This is a bit tricky
|
||||
// to understand. PS image-drawing operations involve two transformation
|
||||
// matrices: (1) A Transformation matrix associated with the image
|
||||
// describes how to map the pixel data (width x height) onto a unit square,
|
||||
// and (2) the document's TM maps the unit square to the desired size and
|
||||
// position. The image TM is technically an inverse TM, i.e. it describes
|
||||
// how to map the unit square onto the pixel array.
|
||||
//
|
||||
// sRect and dRect define the same rectangle, only in different coordinate
|
||||
// systems. Following the translate & scale operations above, the origin
|
||||
// is at [sRect.x, sRect.y]. The "real" origin of image space is thus at
|
||||
// [-sRect.x, -sRect.y] and the pixel data should start at
|
||||
// [-sRect.x + iRect.x, -sRect.y + iRect.y]. These are negated because the
|
||||
// TM is supposed to be an inverse TM.
|
||||
nscoord tmTX = sRect.x - iRect.x;
|
||||
nscoord tmTY = sRect.y - iRect.y;
|
||||
|
||||
n = 0;
|
||||
if ( ( isTopToBottom = aImage->GetIsRowOrderTopToBottom()) == PR_TRUE ) {
|
||||
sRow = sRect.y + sRect.height - 1;
|
||||
eRow = sRect.y;
|
||||
rStep = -1;
|
||||
} else {
|
||||
sRow = sRect.y;
|
||||
eRow = sRect.y + sRect.height;
|
||||
rStep = 1;
|
||||
// In document space, the target rectangle is [dRect.width,
|
||||
// dRect.height]; in image space it's [sRect.width, sRect.height]. So
|
||||
// the proper scale factor is [1/sRect.width, 1/sRect.height], but
|
||||
// again, the output should be an inverse TM so these are inverted.
|
||||
nscoord tmSX = sRect.width;
|
||||
nscoord tmSY = sRect.height;
|
||||
|
||||
// If the image data is in the wrong order, invert the TM, causing
|
||||
// the image to be drawn inverted.
|
||||
if (!anImage->GetIsRowOrderTopToBottom()) {
|
||||
tmTY += tmSY;
|
||||
tmSY = -tmSY;
|
||||
}
|
||||
fprintf(f, "[ %d 0 0 %d %d %d ]\n", tmSX, tmSY, tmTX, tmTY);
|
||||
|
||||
y = sRow;
|
||||
while ( 1 ) {
|
||||
curline = theBits + y * rowData + 3 * sRect.x;
|
||||
for(x=0; x < bytewidth; x+=3) {
|
||||
if (n > 71) {
|
||||
fprintf(mPrintContext->prSetup->tmpBody, "\n");
|
||||
n = 0;
|
||||
// Output the data-reading procedure and the appropriate image command.
|
||||
fputs(" { currentfile rowdata readhexstring pop }", f);
|
||||
if (mPrintSetup->color)
|
||||
fputs(" false 3 colorimage\n", f);
|
||||
else
|
||||
fputs(" image\n", f);
|
||||
|
||||
// Output the image data. The entire image is written, even
|
||||
// if it's partially clipped in the document.
|
||||
int outputCount = 0;
|
||||
PRInt32 bytesPerRow = anImage->GetLineStride();
|
||||
|
||||
for (nscoord y = 0; y < iRect.height; y++) {
|
||||
// calculate the starting point for this row of pixels
|
||||
PRUint8 *row = theBits // Pixel buffer start
|
||||
+ y * bytesPerRow; // Rows already output
|
||||
|
||||
for (nscoord x = 0; x < iRect.width; x++) {
|
||||
PRUint8 *pixel = row + (x * 3);
|
||||
if (mPrintSetup->color)
|
||||
outputCount +=
|
||||
fprintf(f, "%02x%02x%02x", pixel[0], pixel[1], pixel[2]);
|
||||
else
|
||||
outputCount +=
|
||||
fprintf(f, "%02x", NS_RGB_TO_GRAY(pixel[0], pixel[1], pixel[2]));
|
||||
if (outputCount >= 72) {
|
||||
fputc('\n', f);
|
||||
outputCount = 0;
|
||||
}
|
||||
int gray = NS_RGB_TO_GRAY(curline[0], curline[1], curline[2]);
|
||||
fprintf(mPrintContext->prSetup->tmpBody, "%02x", (int) (0xff & gray));
|
||||
curline+=3;
|
||||
n += 2;
|
||||
}
|
||||
y += rStep;
|
||||
if ( isTopToBottom == PR_TRUE && y < eRow ) break;
|
||||
if ( isTopToBottom == PR_FALSE && y >= eRow ) break;
|
||||
}
|
||||
aImage->UnlockImagePixels(PR_FALSE);
|
||||
|
||||
fprintf(mPrintContext->prSetup->tmpBody, "\ngrestore\n");
|
||||
XL_RESTORE_NUMERIC_LOCALE();
|
||||
anImage->UnlockImagePixels(PR_FALSE);
|
||||
|
||||
// Free the PS data buffer and restore the previous graphics state.
|
||||
fputs("\n/rowdata where { /rowdata undef } if\n", f);
|
||||
fputs("grestore\n", f);
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsPostScriptObj.h
|
||||
* Special notes, this on window will blow up since we can not get the bits in a DDB
|
||||
* @update 2/1/99 dwc
|
||||
*/
|
||||
void
|
||||
nsPostScriptObj::colorimage(
|
||||
nsIImage *aImage, const nsRect& sRect, const nsRect& dRect)
|
||||
{
|
||||
PRInt32 rowData, x, y;
|
||||
PRInt32 width, height, bytewidth, cbits, n;
|
||||
PRUint8 *theBits, *curline;
|
||||
PRBool isTopToBottom;
|
||||
PRInt32 sRow, eRow, rStep;
|
||||
|
||||
if(mPrintSetup->color == PR_FALSE) {
|
||||
this->grayimage(aImage, sRect, dRect);
|
||||
return;
|
||||
}
|
||||
|
||||
// No point in scaling images to 0--some printers choke on it (bug 191684)
|
||||
if (dRect.width == 0 || dRect.height == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
aImage->LockImagePixels(PR_FALSE);
|
||||
theBits = aImage->GetBits();
|
||||
|
||||
/* image data might not be available (ex: spacer image) */
|
||||
if (!theBits)
|
||||
{
|
||||
aImage->UnlockImagePixels(PR_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
rowData = aImage->GetLineStride();
|
||||
height = aImage->GetHeight();
|
||||
width = aImage->GetWidth();
|
||||
bytewidth = 3 * sRect.width;
|
||||
cbits = 8;
|
||||
|
||||
XL_SET_NUMERIC_LOCALE();
|
||||
|
||||
FILE *f = mPrintContext->prSetup->tmpBody;
|
||||
fprintf(f, "gsave\n");
|
||||
fprintf(f, "/rowdata %d string def\n", bytewidth);
|
||||
// Translate to the lower left corner of the image
|
||||
translate(dRect.x, dRect.y + dRect.height);
|
||||
// Set the image scale, keeping in mind the Y axis is inverted
|
||||
fprintf(f, "%d %d scale\n", dRect.width, -dRect.height);
|
||||
fprintf(f, "%d %d %d ", sRect.width, sRect.height, cbits);
|
||||
fprintf(f, "[ %d 0 0 %d 0 0 ]\n", sRect.width, sRect.height);
|
||||
fprintf(f, " { currentfile rowdata readhexstring pop }\n");
|
||||
fprintf(f, " false 3 colorimage\n");
|
||||
|
||||
n = 0;
|
||||
if ( ( isTopToBottom = aImage->GetIsRowOrderTopToBottom()) == PR_TRUE ) {
|
||||
sRow = sRect.y + sRect.height - 1;
|
||||
eRow = sRect.y;
|
||||
rStep = -1;
|
||||
} else {
|
||||
sRow = sRect.y;
|
||||
eRow = sRect.y + sRect.height;
|
||||
rStep = 1;
|
||||
}
|
||||
|
||||
y = sRow;
|
||||
while ( 1 ) {
|
||||
curline = theBits + y * rowData + 3 * sRect.x;
|
||||
for(x=0; x < bytewidth; x++) {
|
||||
if (n > 71) {
|
||||
fprintf(f, "\n");
|
||||
n = 0;
|
||||
}
|
||||
fprintf(f, "%02x", (int) (0xff & *curline++));
|
||||
n += 2;
|
||||
}
|
||||
y += rStep;
|
||||
if ( isTopToBottom == PR_TRUE && y < eRow ) break;
|
||||
if ( isTopToBottom == PR_FALSE && y >= eRow ) break;
|
||||
}
|
||||
aImage->UnlockImagePixels(PR_FALSE);
|
||||
|
||||
fprintf(f, "\ngrestore\n");
|
||||
XL_RESTORE_NUMERIC_LOCALE();
|
||||
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsPostScriptObj.h
|
||||
|
|
|
@ -346,22 +346,25 @@ public:
|
|||
void graphics_restore();
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* output a color postscript image
|
||||
* @update 9/30/2003 kherron
|
||||
* @param aImage The image to draw
|
||||
* sRect The portion of the image to draw
|
||||
* dRect Where on the page to place the image
|
||||
* Draw an image. dRect may be thought of as a hole in the document
|
||||
* page, through which we can see another page containing the image.
|
||||
* sRect is the portion of the image page which is visible through the
|
||||
* hole in the document. iRect is the portion of the image page which
|
||||
* contains the image represented by anImage. sRect and iRect may be
|
||||
* at arbitrary positions relative to each other.
|
||||
*
|
||||
* @update 11/25/2003 kherron
|
||||
* @param anImage Image to draw
|
||||
* @param dRect Rectangle describing where on the page the image
|
||||
* should appear. Units are twips.
|
||||
* @param sRect Rectangle describing the portion of the image that
|
||||
* appears on the page, i.e. the part of the image's
|
||||
* coordinate space that maps to dRect.
|
||||
* @param iRect Rectangle describing the portion of the image's
|
||||
* coordinate space covered by the image pixel data.
|
||||
*/
|
||||
void colorimage(nsIImage *aImage, const nsRect& sRect, const nsRect& dRect);
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* output a grayscale postscript image
|
||||
* @update 9/30/2003 kherron
|
||||
* @param aImage The image to draw
|
||||
* sRect The portion of the image to draw
|
||||
* dRect Where on the page to place the image
|
||||
*/
|
||||
void grayimage(nsIImage *aImage, const nsRect& sRect, const nsRect& dRect);
|
||||
void draw_image(nsIImage *anImage,
|
||||
const nsRect& sRect, const nsRect& iRect, const nsRect& dRect);
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* ???
|
||||
|
|
|
@ -184,15 +184,18 @@ nsRenderingContextPS::Init(nsIDeviceContext* aContext)
|
|||
NS_ENSURE_TRUE(nsnull != aContext, NS_ERROR_NULL_POINTER);
|
||||
|
||||
mContext = aContext;
|
||||
mContext->GetDevUnitsToAppUnits(mP2T);
|
||||
|
||||
mPSObj = NS_REINTERPRET_CAST(nsDeviceContextPS *, mContext.get())->GetPrintContext();
|
||||
|
||||
NS_ENSURE_TRUE(nsnull != mPSObj, NS_ERROR_NULL_POINTER);
|
||||
|
||||
// Set the transformation matrix to identity. Baseline coordinate
|
||||
// conversions are performed by the PS interpreter.
|
||||
mTranMatrix->SetToIdentity();
|
||||
mContext->GetDevUnitsToAppUnits(mP2T);
|
||||
// Layout's coordinate system places the origin at top left with Y
|
||||
// increasing down; PS places the origin at bottom left with Y increasing
|
||||
// upward. Both systems use twips for units, so no resizing is needed.
|
||||
mTranMatrix->SetToScale(1.0, -1.0);
|
||||
mTranMatrix->AddTranslation(0, -mPSObj->mPrintSetup->height);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1251,8 +1254,7 @@ nsRenderingContextPS::DrawImage(imgIContainer *aImage, const nsRect * aSrcRect,
|
|||
NS_IMETHODIMP
|
||||
nsRenderingContextPS::DrawScaledImage(imgIContainer *aImage, const nsRect * aSrcRect, const nsRect * aDestRect)
|
||||
{
|
||||
nsRect dr;
|
||||
nsRect sr;
|
||||
nsRect sr, ir, dr;
|
||||
|
||||
// Transform the destination rectangle.
|
||||
dr = *aDestRect;
|
||||
|
@ -1273,7 +1275,8 @@ nsRenderingContextPS::DrawScaledImage(imgIContainer *aImage, const nsRect * aSrc
|
|||
nsCOMPtr<nsIImage> img(do_GetInterface(iframe));
|
||||
if (!img) return NS_ERROR_FAILURE;
|
||||
|
||||
mPSObj->colorimage(img, sr, dr);
|
||||
iframe->GetRect(ir);
|
||||
mPSObj->draw_image(img, sr, ir, dr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче