00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "scpainterex_ps2.h"
00029
00030 #include <cfloat>
00031 #include <QPaintDevice>
00032 #include <QPixmap>
00033 #include <QImage>
00034
00035 #include <iostream>
00036 #include <memory>
00037 using namespace std;
00038
00039 #include <cmath>
00040 #include "util.h"
00041 #include "sccolorengine.h"
00042
00043 ScPs2OutputParams::ScPs2OutputParams(ScribusDoc* doc)
00044 {
00045 document = doc;
00046 colorMode = ScPainterExBase::rgbMode;
00047 reloadImages = true;
00048 resolution = 72;
00049 useProfiles = false;
00050 toGray = false;
00051 mirrorH = false;
00052 mirrorV = false;
00053 hProfile = NULL;
00054 rgbToOutputColorTransform = NULL;
00055 rgbToOutputImageTransform = NULL;
00056 cmykToOutputColorTransform = NULL;
00057 cmykToOutputImageTransform = NULL;
00058 }
00059
00060 ScPainterEx_Ps2::ScPainterEx_Ps2(QIODevice* iodev, QRect& rect, ScPs2OutputParams& options ) : ScPainterExBase()
00061 {
00062 m_stream.setDevice( iodev );
00063 m_colorMode = options.colorMode;
00064 m_encoding = Ascii85Encoding;
00065 m_options = options;
00066 m_width = rect.width();
00067 m_height= rect.height();
00068 m_x = rect.left();
00069 m_y = rect.top();
00070 m_fillColor = ScColorShade( QColor(0,0,0), 100 );
00071 m_strokeColor = ScColorShade( QColor(0,0,0), 100 );
00072 m_fillTrans = 1.0;
00073 m_strokeTrans = 1.0;
00074 m_fillRule = true;
00075 m_fillMode = 1;
00076 m_lineWidth = 1.0;
00077 m_offset = 0;
00078 m_array.clear();
00079 m_lineEnd = Qt::SquareCap;
00080 m_lineJoin = Qt::RoundJoin;
00081 m_fillGradient = VGradientEx(VGradientEx::linear);
00082 m_strokeGradient = VGradientEx(VGradientEx::linear);
00083 m_matrix = QMatrix();
00084 m_pageTrans = QMatrix();
00085
00086 m_pathIsClosed = true;
00087 m_drawingClosedPath = false;
00088
00089 m_deviceDimX = 0;
00090 m_deviceDimY = 0;
00091 m_deviceResX = 0;
00092 m_deviceResY = 0;
00093 clear();
00094 }
00095
00096 ScPainterEx_Ps2::~ScPainterEx_Ps2()
00097 {
00098 }
00099
00100 ScPainterExBase::ImageMode ScPainterEx_Ps2::imageMode()
00101 {
00102 ImageMode imageMode;
00103 if (m_options.hProfile && m_options.rgbToOutputImageTransform && m_options.cmykToOutputImageTransform)
00104 imageMode = rawImages;
00105 else if (m_colorMode == cmykMode)
00106 imageMode = cmykImages;
00107 else
00108 imageMode = rgbImages;
00109 return imageMode;
00110 }
00111
00112 void ScPainterEx_Ps2::transformImage( QImage* image, uchar* data, int scan)
00113 {
00114 int rgb, grey;
00115 int imageWidth = image->width();
00116 int imageHeight = image->height();
00117
00118 QRgb* pscani;
00119 uchar *pscand;
00120
00121 pscand = data;
00122 for ( int j = 0; j < imageHeight; j++ )
00123 {
00124 pscani = (QRgb *) image->scanLine(j);
00125 for (int i = 0; i < imageWidth; i++ )
00126 {
00127 rgb = pscani[i];
00128 grey = qRound(0.3 * qRed(rgb)) + qRound(0.59 * qGreen(rgb)) + qRound(0.11 * qBlue(rgb));
00129 pscand[i] = grey;
00130 }
00131 pscand += scan;
00132 }
00133
00134 }
00135
00136 void ScPainterEx_Ps2::begin()
00137 {
00138 }
00139
00140 void ScPainterEx_Ps2::end()
00141 {
00142
00143 }
00144
00145 void ScPainterEx_Ps2::clear()
00146 {
00147
00148 }
00149
00150 void ScPainterEx_Ps2::clear( ScColorShade &c )
00151 {
00152
00153 }
00154
00155 const QMatrix ScPainterEx_Ps2::worldMatrix()
00156 {
00157 return m_matrix;
00158 }
00159
00160 void ScPainterEx_Ps2::setWorldMatrix( const QMatrix &mat )
00161 {
00162 m_matrix = mat;
00163 }
00164
00165 void ScPainterEx_Ps2::transformPoint( const FPoint& in, FPoint& out )
00166 {
00167 double x, y;
00168 x = in.x() * m_matrix.m11() + in.y() * m_matrix.m21() + m_matrix.dx();
00169 y = in.x() * m_matrix.m12() + in.y() * m_matrix.m22() + m_matrix.dy();
00170 out.setX( x );
00171 out.setY( y );
00172 }
00173
00174 void ScPainterEx_Ps2::transformPoints( const FPoint* ArrayIn, FPoint* ArrayOut, uint length )
00175 {
00176 for( uint i = 0; i < length; i++ )
00177 {
00178 transformPoint( ArrayIn[i], ArrayOut[i] );
00179 }
00180 }
00181
00182 void ScPainterEx_Ps2::translate( double x, double y )
00183 {
00184 m_matrix.translate(x, y);
00185 }
00186
00187 void ScPainterEx_Ps2::rotate( double r )
00188 {
00189 m_matrix.rotate(r);
00190 }
00191
00192 void ScPainterEx_Ps2::scale( double x, double y )
00193 {
00194 m_matrix.scale(x, y);
00195 }
00196
00197 void ScPainterEx_Ps2::moveTo( const double &x, const double &y )
00198 {
00199 FPoint pp( x, y );
00200 transformPoint( pp, pp );
00201 m_stream << QString("%1 %2 moveto\n").arg(pp.x()).arg(pp.y());
00202 }
00203
00204 void ScPainterEx_Ps2::lineTo( const double &x, const double &y )
00205 {
00206 FPoint pp( x, y );
00207 transformPoint( pp, pp );
00208 m_stream << QString("%1 %2 lineto\n").arg(pp.x()).arg(pp.y());
00209 }
00210
00211 void ScPainterEx_Ps2::curveTo( FPoint p1, FPoint p2, FPoint p3 )
00212 {
00213 FPoint pps[3];
00214 pps[0].setXY( p1.x(), p1.y() );
00215 pps[1].setXY( p2.x(), p2.y() );
00216 pps[2].setXY( p3.x(), p3.y() );
00217 transformPoints( pps, pps, 3 );
00218 m_stream << QString("%1 %2 %3 %4 %5 %6 curveto\n").arg(pps[0].x()).arg(pps[0].y()).arg(pps[1].x()).arg(pps[1].y()).arg(pps[2].x()).arg(pps[2].y());
00219 }
00220
00221 void ScPainterEx_Ps2::newPath()
00222 {
00223 m_stream << "newpath\n";
00224
00225 }
00226
00227 void ScPainterEx_Ps2::closePath()
00228 {
00229 m_stream << "closepath\n";
00230 m_pathIsClosed = true;
00231 }
00232
00233 void ScPainterEx_Ps2::setFillRule( bool fillRule )
00234 {
00235 m_fillRule = fillRule;
00236 }
00237
00238 void ScPainterEx_Ps2::setFillMode( int fill )
00239 {
00240 m_fillMode = fill;
00241 }
00242
00243 void ScPainterEx_Ps2::setGradient(VGradientEx::Type mode, FPoint orig, FPoint vec, FPoint foc)
00244 {
00245 m_fillGradient.setType(mode);
00246 m_fillGradient.setOrigin(orig);
00247 m_fillGradient.setVector(vec);
00248 m_fillGradient.setFocalPoint(foc);
00249 }
00250
00251 void ScPainterEx_Ps2::setPattern( ScPattern* pattern, QMatrix& patternTransform )
00252 {
00253 m_pattern = pattern;
00254 m_patternTransform = patternTransform;
00255 }
00256
00257 void ScPainterEx_Ps2::fillTextPath()
00258 {
00259 drawVPath( 0 );
00260 }
00261
00262 void ScPainterEx_Ps2::strokeTextPath()
00263 {
00264 if( m_lineWidth == 0 )
00265 return;
00266 drawVPath( 1 );
00267 }
00268
00269 void ScPainterEx_Ps2::fillPath()
00270 {
00271 if(!m_pathIsClosed)
00272 closePath();
00273 if( m_fillMode != 0)
00274 drawVPath( 0 );
00275 }
00276
00277 void ScPainterEx_Ps2::strokePath()
00278 {
00279 if( m_lineWidth == 0 )
00280 return;
00281 save();
00282 if(!m_pathIsClosed)
00283 closePath();
00284 drawVPath( 1 );
00285 restore();
00286 }
00287
00288 ScColorShade ScPainterEx_Ps2::pen()
00289 {
00290 return m_strokeColor;
00291 }
00292
00293 ScColorShade ScPainterEx_Ps2::brush()
00294 {
00295 return m_fillColor;
00296 }
00297
00298 void ScPainterEx_Ps2::setPen( const ScColorShade &c )
00299 {
00300 m_strokeColor = c;
00301 }
00302
00303 void ScPainterEx_Ps2::setPen( const ScColorShade &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo )
00304 {
00305 m_offset = 0;
00306 m_strokeColor = c;
00307 m_lineWidth = w;
00308 m_lineEnd = ca;
00309 m_lineJoin = jo;
00310 double Dt = qMax(2*w, 1.0);
00311 double Da = qMax(6*w, 1.0);
00312 m_array.clear();
00313 if (st == Qt::DashLine)
00314 m_array << Da << Dt;
00315 else if (st == Qt::DotLine)
00316 m_array << Dt;
00317 else if (st == Qt::DashDotLine)
00318 m_array << Da << Dt << Dt << Dt;
00319 else if (st == Qt::DashDotDotLine)
00320 m_array << Da << Dt << Dt << Dt << Dt << Dt;
00321 }
00322
00323 void ScPainterEx_Ps2::setLineWidth( double w )
00324 {
00325 m_lineWidth = w;
00326 }
00327
00328 void ScPainterEx_Ps2::setPenOpacity( double op )
00329 {
00330 m_strokeTrans = op;
00331 }
00332
00333 void ScPainterEx_Ps2::setDash(const QList<double>& array, double ofs)
00334 {
00335 m_array = array;
00336 m_offset = ofs;
00337 }
00338
00339 void ScPainterEx_Ps2::setBrush( const ScColorShade &c )
00340 {
00341 m_fillColor = c;
00342 }
00343
00344 void ScPainterEx_Ps2::setBrushOpacity( double op )
00345 {
00346 m_fillTrans = op;
00347 }
00348
00349 void ScPainterEx_Ps2::setOpacity( double op )
00350 {
00351 m_fillTrans = op;
00352 m_strokeTrans = op;
00353 }
00354
00355 void ScPainterEx_Ps2::setFont( const QFont &f)
00356 {
00357 m_font = f;
00358 }
00359
00360 QFont ScPainterEx_Ps2::font()
00361 {
00362 return m_font;
00363 }
00364
00365 void ScPainterEx_Ps2::save()
00366 {
00367 m_stack.push( m_matrix );
00368 m_stream << "gsave\n";
00369 }
00370
00371 void ScPainterEx_Ps2::restore()
00372 {
00373 m_matrix = m_stack.pop();
00374 m_stream << "grestore\n";
00375 }
00376
00377 void ScPainterEx_Ps2::setRasterOp( int )
00378 {
00379 }
00380
00381 void ScPainterEx_Ps2::drawVPath( int mode )
00382 {
00383 save();
00384 if (mode == 0)
00385 {
00386 if (m_fillMode == ScPainterExBase::Gradient)
00387 drawGradient( m_fillGradient );
00388 else
00389 putColor( m_fillColor, true );
00390 }
00391 else
00392 {
00393 double m11 = m_matrix.m11();
00394 double m12 = m_matrix.m12();
00395 double m21 = m_matrix.m21();
00396 double m22 = m_matrix.m22();
00397 double norm2 = m11 * m11 + m12 * m12 + m21 * m21 + m22 * m22;
00398 double penScale = sqrt(norm2 /2.0);
00399 double penWidth = (int) (m_lineWidth * penScale);
00400 m_stream << QString("%1 setlinewidth\n").arg(penWidth);
00401
00402 m_stream << "[";
00403 for( int i = 0; i < m_array.count();++ i )
00404 {
00405 m_stream << QString("%1").arg(m_array[i]) << " ";
00406 }
00407 m_stream << "]";
00408 m_stream << " 0 setdash\n";
00409
00410 if( m_lineEnd == Qt::RoundCap )
00411 m_stream << "1 setlinecap\n";
00412 else if( m_lineEnd == Qt::SquareCap )
00413 m_stream << "2 setlinecap\n";
00414 else if( m_lineEnd == Qt::FlatCap )
00415 m_stream << "0 setlinecap\n";
00416 else
00417 m_stream << "0 setlinecap\n";
00418
00419 if( m_lineJoin == Qt::RoundJoin )
00420 m_stream << "1 setlinejoin\n";
00421 else if( m_lineJoin == Qt::BevelJoin )
00422 m_stream << "2 setlinejoin\n";
00423 else if( m_lineJoin == Qt::MiterJoin )
00424 m_stream << "0 setlinejoin\n";
00425 else
00426 m_stream << "0 setlinejoin\n";
00427
00428 putColor(m_strokeColor, false);
00429 }
00430 restore();
00431 }
00432
00433 void ScPainterEx_Ps2::setClipPath()
00434 {
00435
00436 m_stream << "clip newpath\n";
00437 m_clipBBox = m_pathBBox;
00438 }
00439
00440 void ScPainterEx_Ps2::putColor( ScColorShade& colorShade, bool doFill )
00441 {
00442 ColorMode colorMode = m_colorMode;
00443 int r = 0, g = 0, b = 0, gray = 0;
00444 int c = 0, m = 0, y = 0, k = 0;
00445 if ( m_options.toGray )
00446 {
00447 RGBColor rgb;
00448 ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
00449 rgb.getValues(r, g, b);
00450 gray = qRound(0.3 * r + 0.59 * g + 0.11 * b);
00451 if ( doFill && m_fillRule )
00452 m_stream << QString("%1 setgray eofill\n").arg(gray/255.0);
00453 else if ( doFill )
00454 m_stream << QString("%1 setgray fill\n").arg(gray/255.0);
00455 else
00456 m_stream << QString("%1 setgray stroke\n").arg(gray/255.0);
00457 return;
00458 }
00459 else if ( m_options.hProfile && m_options.rgbToOutputColorTransform && m_options.cmykToOutputColorTransform)
00460 {
00461 DWORD colorIn[4];
00462 DWORD colorOut[4];
00463 cmsHTRANSFORM cmsTranform = NULL;
00464 if( colorShade.color.getColorModel() == colorModelRGB )
00465 {
00466 RGBColor rgb;
00467 ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
00468 colorIn[0] = rgb.r;
00469 colorIn[1] = rgb.g;
00470 colorIn[2] = rgb.b;
00471 colorMode = rgbMode;
00472 cmsTranform = m_options.rgbToOutputColorTransform;
00473 }
00474 else
00475 {
00476 CMYKColor cmyk;
00477 ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
00478 colorIn[0] = cmyk.c;
00479 colorIn[1] = cmyk.m;
00480 colorIn[2] = cmyk.y;
00481 colorIn[3] = cmyk.k;
00482 colorMode = cmykMode;
00483 cmsTranform = m_options.cmykToOutputColorTransform;
00484 }
00485 cmsDoTransform( cmsTranform, colorIn, colorOut, 1 );
00486 if (static_cast<int>(cmsGetColorSpace(m_options.hProfile)) == icSigRgbData)
00487 {
00488 r = colorOut[0] / 257;
00489 g = colorOut[1] / 257;
00490 b = colorOut[2] / 257;
00491 colorMode = rgbMode;
00492 }
00493 else if (static_cast<int>(cmsGetColorSpace(m_options.hProfile)) == icSigCmykData)
00494 {
00495 c = colorOut[0] / 257;
00496 m = colorOut[1] / 257;
00497 y = colorOut[2] / 257;
00498 k = colorOut[3] / 257;
00499 colorMode = cmykMode;
00500 }
00501 }
00502 else if ( m_colorMode == rgbMode )
00503 {
00504 RGBColor rgb;
00505 colorMode = rgbMode;
00506 ScColorEngine::getShadeColorRGB(colorShade.color, m_options.document, rgb, colorShade.shade);
00507 rgb.getValues(r, g, b);
00508 }
00509 else if ( m_colorMode == cmykMode )
00510 {
00511 CMYKColor cmyk;
00512 colorMode = cmykMode;
00513 ScColorEngine::getShadeColorCMYK(colorShade.color, m_options.document, cmyk, colorShade.shade);
00514 cmyk.getValues(c, m, y, k);
00515 }
00516
00517
00518 if ( colorMode == rgbMode )
00519 {
00520 if ( doFill && m_fillRule )
00521 m_stream << QString("%1 %2 %3 setrgbcolor eofill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
00522 else if ( doFill )
00523 m_stream << QString("%1 %2 %3 setrgbcolor fill\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
00524 else
00525 m_stream << QString("%1 %2 %3 setrgbcolor stroke\n").arg(r/255.0).arg(g/255.0).arg(b/255.0);
00526 }
00527 else if ( colorMode == cmykMode )
00528 {
00529 QString colstr1 = QString("%1 %2 %3 %4 setcmykcolor").arg(c/255.0).arg(m/255.0).arg(y/255.0).arg(k/255.0);
00530 if ( doFill && m_fillRule )
00531 m_stream << colstr1 << " eofill\n";
00532 else if ( doFill )
00533 m_stream << colstr1 << " fill\n";
00534 else
00535 m_stream << colstr1 << " stroke\n";
00536 }
00537 }
00538
00539 void ScPainterEx_Ps2::drawImage( ScImage *image, ScPainterExBase::ImageMode mode )
00540 {
00541 bool rgbMode = (mode == ScPainterExBase::rgbImages || mode == ScPainterExBase::rgbProofImages);
00542 bool rgbPicture = rgbMode || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceRGB);
00543 bool cmykPicture = (mode == ScPainterExBase::cmykImages || (mode == ScPainterExBase::rawImages && image->imgInfo.colorspace == ColorSpaceCMYK));
00544
00545 if( rgbPicture )
00546 drawRGBImage_ps2( image );
00547 else if( cmykPicture )
00548 drawCMYKImage_ps2( image );
00549 else
00550 qDebug( "ScPainterEx_Ps2::drawImage() : unknown image type" );
00551 }
00552
00553 void ScPainterEx_Ps2::drawRGBImage_ps2( ScImage *image )
00554 {
00555 save();
00556 QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
00557 m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
00558 m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
00559 m_stream << "/DeviceRGB setcolorspace\n";
00560 if (hasAlphaChannel(image))
00561 {
00562 QImage imgTemp = image->qImage();
00563 QImage mask = imgTemp.createAlphaMask();
00564 if (m_encoding == Ascii85Encoding)
00565 {
00566 m_stream << "currentfile /ASCII85Decode filter /ReusableStreamDecode filter\n";
00567 writeRGBImageToStream_Ascii85(image);
00568 }
00569 else
00570 {
00571 m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
00572 writeRGBImageToStream_AsciiHex(image);
00573 }
00574 m_stream << "/myImage exch def\n";
00575 m_stream << "currentfile /ASCIIHexDecode filter /ReusableStreamDecode filter\n";
00576 writeMaskToStream(&mask);
00577 m_stream << "/myMask exch def\n";
00578 m_stream << QString("<<\n");
00579 m_stream << QString(" /PaintType 1\n");
00580 m_stream << QString(" /PatternType 1\n");
00581 m_stream << QString(" /TilingType 3\n");
00582 m_stream << QString(" /BBox [ 0 0 1 1 ]\n");
00583 m_stream << QString(" /XStep 2\n");
00584 m_stream << QString(" /YStep 2\n");
00585 m_stream << QString(" /PaintProc {\n");
00586 m_stream << QString(" pop\n");
00587 m_stream << QString(" 0 0 0 setrgbcolor\n");
00588 m_stream << QString(" <<\n");
00589 m_stream << QString(" /ImageType 1\n");
00590 m_stream << QString(" /Width %1\n").arg(image->width());
00591 m_stream << QString(" /Height %1\n").arg(image->height());
00592 m_stream << QString(" /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
00593 m_stream << QString(" /BitsPerComponent 8\n");
00594 m_stream << QString(" /Decode [0 1 0 1 0 1]\n");
00595 m_stream << QString(" /DataSource myImage\n");
00596 m_stream << QString(" >>\n");
00597 m_stream << QString(" image\n");
00598 m_stream << QString(" }\n");
00599 m_stream << QString(">> matrix makepattern setpattern\n");
00600 m_stream << QString("<<\n");
00601 m_stream << QString(" /ImageType 1\n");
00602 m_stream << QString(" /Width %1 \n").arg(image->width());
00603 m_stream << QString(" /Height %1 \n").arg(image->height());
00604 m_stream << QString(" /BitsPerComponent 1\n");
00605 m_stream << QString(" /Decode [1 0]\n");
00606 m_stream << QString(" /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
00607 m_stream << QString(" /DataSource myMask\n");
00608 m_stream << QString(">>\n");
00609 m_stream << QString("imagemask\n");
00610 }
00611 else
00612 {
00613 m_stream << QString("<<\n");
00614 m_stream << QString(" /ImageType 1\n");
00615 m_stream << QString(" /Width %1\n").arg(image->width());
00616 m_stream << QString(" /Height %1\n").arg(image->height());
00617 m_stream << QString(" /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
00618 m_stream << QString(" /Decode [0 1 0 1 0 1]\n");
00619 m_stream << QString(" /BitsPerComponent 8\n");
00620
00621 if (m_encoding == Ascii85Encoding)
00622 {
00623 m_stream << QString(" /DataSource currentfile /ASCII85Decode filter\n");
00624 m_stream << QString(">>\n");
00625 m_stream << "image\n";
00626 writeRGBImageToStream_Ascii85(image);
00627 }
00628 else
00629 {
00630 m_stream << QString(" /DataSource currentfile /ASCIIHexDecode filter\n");
00631 m_stream << QString(">>\n");
00632 m_stream << "image\n";
00633 writeRGBImageToStream_AsciiHex(image);
00634 }
00635 }
00636 restore();
00637 }
00638
00639 void ScPainterEx_Ps2::drawCMYKImage_ps2( ScImage *image )
00640 {
00641 save();
00642 QString sc("[%1 %2 %3 %4 %5 %6] concat\n");
00643 m_stream << sc.arg(m_matrix.m11()).arg(m_matrix.m12()).arg(m_matrix.m21()).arg(m_matrix.m22()).arg(m_matrix.dx()).arg(m_matrix.dy());
00644 m_stream << QString("%1 %2 scale\n").arg(image->width()).arg(image->height());
00645 m_stream << "/DeviceCMYK setcolorspace\n";
00646
00647 bool haveMask = false;
00648 if (haveMask)
00649 {
00650
00651 }
00652 else
00653 {
00654 m_stream << "<<\n";
00655 m_stream << QString(" /ImageType 1\n");
00656 m_stream << QString(" /Width %1\n").arg(image->width());
00657 m_stream << QString(" /Height %1\n").arg(image->height());
00658 m_stream << QString(" /ImageMatrix [ %1 0 0 %2 0 0 ]\n").arg(image->width()).arg(image->height());
00659 m_stream << QString(" /Decode [0 1 0 1 0 1 0 1]\n");
00660 m_stream << QString(" /BitsPerComponent 8\n");
00661
00662 if (m_encoding == Ascii85Encoding)
00663 {
00664 m_stream << QString(" /DataSource currentfile /ASCII85Decode filter\n");
00665 m_stream << QString(">>\n");
00666 m_stream << "image\n";
00667 writeCMYKImageToStream_Ascii85(image);
00668 }
00669 else
00670 {
00671 m_stream << QString(" /DataSource currentfile /ASCIIHexDecode filter\n");
00672 m_stream << QString(">>\n");
00673 m_stream << "image\n";
00674 writeCMYKImageToStream_AsciiHex(image);
00675 }
00676 }
00677 restore();
00678 }
00679
00680 bool ScPainterEx_Ps2::hasAlphaChannel( ScImage* image )
00681 {
00682 bool hasAlpha = false;
00683 int width = image->width();
00684 int height = image->height();
00685 for( int y = 0; y < height; y++ )
00686 {
00687 QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
00688 for( int x = 0; x < width; ++x )
00689 {
00690 if( qAlpha(*imageBits) != 255 )
00691 {
00692 hasAlpha = true;
00693 break;
00694 }
00695 imageBits++;
00696 }
00697 }
00698 return hasAlpha;
00699 }
00700
00701 void ScPainterEx_Ps2::writeMaskToStream( QImage* image )
00702 {
00703 int length = 0;
00704 unsigned char bits;
00705 int width = image->width() / 8;
00706 int height = image->height();
00707 if ((image->width() % 8) != 0)
00708 width++;
00709 for( int y = 0; y < height; ++y )
00710 {
00711 unsigned char* imageBits = image->scanLine(y);
00712 for( int x = 0; x < width; x++ )
00713 {
00714 length++;
00715 bits = imageBits[x];
00716 m_stream << toHex(bits);
00717 if ( (length % 49) == 0 )
00718 m_stream << "\n";
00719 }
00720 }
00721 m_stream << "\n>\n";
00722 }
00723
00724 void ScPainterEx_Ps2::writeRGBImageToStream_Ascii85( ScImage* image )
00725 {
00726 int cindex;
00727 int pending = 0, written = 0;
00728 bool allZero = true;
00729 unsigned char four_tuple[4];
00730 const char* ascii85;
00731 quint32 value;
00732
00733 int width = image->width();
00734 int height = image->height();
00735 for( int y = 0; y < height; ++y )
00736 {
00737 QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
00738 for( int x = 0; x < width; ++x )
00739 {
00740 cindex = 0;
00741 while (cindex < 3)
00742 {
00743 if (cindex == 0)
00744 four_tuple[pending++] = (uchar) qRed(*imageBits);
00745 else if (cindex == 1)
00746 four_tuple[pending++] = (uchar) qGreen(*imageBits);
00747 else if (cindex == 2)
00748 four_tuple[pending++] = (uchar) qBlue(*imageBits);
00749 if (pending == 4)
00750 {
00751 value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
00752 ascii85 = toAscii85(value, allZero);
00753 if (allZero)
00754 m_stream << "z";
00755 else
00756 m_stream << ascii85;
00757 written += ((allZero) ? 1 : 5);
00758 if (written > 75)
00759 {
00760 m_stream << "\n";
00761 written = 0;
00762 }
00763 pending = 0;
00764 }
00765 ++cindex;
00766 }
00767
00768 }
00769 }
00770 if (pending)
00771 {
00772 unsigned char five_tuple[6];
00773 memset (four_tuple + pending, 0, 4 - pending);
00774 value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
00775 ascii85 = toAscii85(value, allZero);
00776 memcpy (five_tuple, ascii85, 5);
00777 five_tuple[pending + 1] = 0;
00778 m_stream << (const char*) five_tuple;
00779 }
00780 m_stream << "~>\n";
00781 }
00782
00783 void ScPainterEx_Ps2::writeRGBImageToStream_AsciiHex ( ScImage* image )
00784 {
00785 int length = 0;
00786 int width = image->width();
00787 int height = image->height();
00788 for( int y = 0; y < height; ++y )
00789 {
00790 QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
00791 for( int x = 0; x < width; ++x )
00792 {
00793 length++;
00794 uchar r = (uchar) qRed(*imageBits);
00795 m_stream << toHex(r);
00796 uchar g = (uchar) qGreen(*imageBits);
00797 m_stream << toHex(g);
00798 uchar b = (uchar) qBlue(*imageBits);
00799 m_stream << toHex(b);
00800 if ( (length % 17) == 0 )
00801 m_stream << "\n";
00802 imageBits++;
00803 }
00804 }
00805 m_stream << "\n>\n";
00806 }
00807
00808 void ScPainterEx_Ps2::writeCMYKImageToStream_Ascii85( ScImage* image )
00809 {
00810 int written = 0;
00811 bool allZero = true;
00812 unsigned char four_tuple[4];
00813 const char* ascii85;
00814 quint32 value;
00815
00816 int width = image->width();
00817 int height = image->height();
00818 for( int y = 0; y < height; y++ )
00819 {
00820 QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
00821 for( int x = 0; x < width; x++ )
00822 {
00823 four_tuple[0] = (uchar) qRed(*imageBits);
00824 four_tuple[1] = (uchar) qGreen(*imageBits);
00825 four_tuple[2] = (uchar) qBlue(*imageBits);
00826 four_tuple[3] = (uchar) qAlpha(*imageBits);
00827 value = four_tuple[0] << 24 | four_tuple[1] << 16 | four_tuple[2] << 8 | four_tuple[3];
00828 ascii85 = toAscii85(value, allZero);
00829 if (allZero)
00830 m_stream << "z";
00831 else
00832 m_stream << ascii85;
00833 written += ((allZero) ? 1 : 5);
00834 if (written > 75)
00835 {
00836 m_stream << "\n";
00837 written = 0;
00838 }
00839 imageBits++;
00840 }
00841 }
00842 m_stream << "~>\n";
00843 }
00844
00845 void ScPainterEx_Ps2::writeCMYKImageToStream_AsciiHex( ScImage* image )
00846 {
00847 int length = 0;
00848 int width = image->width();
00849 int height = image->height();
00850 for( int y = 0; y < height; ++y )
00851 {
00852 QRgb* imageBits = (QRgb*)(image->qImage().scanLine(y));
00853 for( int x = 0; x < width; ++x )
00854 {
00855 length++;
00856 uchar c = (uchar) qRed(*imageBits);
00857 m_stream << toHex(c);
00858 uchar m = (uchar) qGreen(*imageBits);
00859 m_stream << toHex(m);
00860 uchar y = (uchar) qBlue(*imageBits);
00861 m_stream << toHex(y);
00862 uchar k = (uchar) qAlpha(*imageBits);
00863 m_stream << toHex(k);
00864 if ( (length % 13) == 0 )
00865 m_stream << "\n";
00866 imageBits++;
00867 }
00868 }
00869 m_stream << "\n>\n";
00870 }
00871
00872 void ScPainterEx_Ps2::setupPolygon(FPointArray *points, bool closed)
00873 {
00874 bool nPath = true;
00875 FPoint np, np1, np2, np3;
00876 if (points->size() > 3)
00877 {
00878 newPath();
00879 for (uint poi=0; poi<points->size()-3; poi += 4)
00880 {
00881 if (points->point(poi).x() > 900000)
00882 {
00883 nPath = true;
00884 continue;
00885 }
00886 if (nPath)
00887 {
00888 np = points->point(poi);
00889
00890 moveTo( np.x(), np.y() );
00891 nPath = false;
00892 }
00893 np = points->point(poi);
00894 np1 = points->point(poi+1);
00895 np2 = points->point(poi+3);
00896 np3 = points->point(poi+2);
00897 if ((np == np1) && (np2 == np3))
00898 lineTo( np3.x(), np3.y() );
00899 else
00900 curveTo(np1, np2, np3);
00901 }
00902 if (closed)
00903 {
00904 closePath();
00905 m_drawingClosedPath = true;
00906 }
00907 }
00908 getPathBoundingBox( points, m_pathBBox );
00909 }
00910
00911 void ScPainterEx_Ps2::setupTextPolygon(FPointArray *points)
00912 {
00913 bool nPath = true;
00914 FPoint np, np1, np2, np3;
00915 if (points->size() > 3)
00916 {
00917 newPath();
00918 for (uint poi=0; poi<points->size()-3; poi += 4)
00919 {
00920 if (points->point(poi).x() > 900000)
00921 {
00922 nPath = true;
00923 continue;
00924 }
00925 if (nPath)
00926 {
00927 np = points->point(poi);
00928
00929 moveTo( np.x(), np.y() );
00930 nPath = false;
00931 }
00932 np.setXY( points->point(poi).x(), points->point(poi).y() );
00933 np1.setXY( points->point(poi+1).x(), points->point(poi+1).y() );
00934 np2.setXY( points->point(poi+3).x(), points->point(poi+3).y() );
00935 np3.setXY( points->point(poi+2).x(), points->point(poi+2).y() );
00936 if ((np == np1) && (np2 == np3))
00937 lineTo( np3.x(), np3.