Scribus Developer Documentation - API
logo-pen

Scribus Developer Documentation - API

scpageoutput.cpp

Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include "scpageoutput.h"
00008 
00009 #include <QList>
00010 #include <QPointF>
00011 #include <QRectF>
00012 #include <QStack>
00013 
00014 #include "cmsettings.h"
00015 #include "commonstrings.h"
00016 #include "page.h"
00017 #include "pageitem.h"
00018 #include "pageitem_imageframe.h"
00019 #include "pageitem_line.h"
00020 #include "pageitem_pathtext.h"
00021 #include "pageitem_polygon.h"
00022 #include "pageitem_polyline.h"
00023 #include "pageitem_textframe.h"
00024 #include "prefsmanager.h"
00025 #include "scfonts.h"
00026 #include "scimage.h"
00027 #include "scpattern.h"
00028 #include "scribus.h"
00029 #include "scribusdoc.h"
00030 #include "util.h"
00031 #include "util_formats.h"
00032 #include "util_math.h"
00033 
00034 
00035 MarksOptions::MarksOptions(void)
00036 {
00037     markOffset = 0.0;
00038     BleedTop = 0.0;
00039     BleedLeft = 0.0;
00040     BleedRight = 0.0;
00041     BleedBottom = 0.0;
00042     cropMarks = false;
00043     bleedMarks = false;
00044     registrationMarks = false;
00045     colorMarks = false;
00046     docInfoMarks = false;
00047 }
00048 
00049 MarksOptions::MarksOptions(struct PrintOptions& opt)
00050 {
00051     markOffset = opt.markOffset;
00052     BleedTop = opt.bleeds.Top;
00053     BleedLeft = opt.bleeds.Left;
00054     BleedRight = opt.bleeds.Right;
00055     BleedBottom = opt.bleeds.Bottom;
00056     cropMarks = opt.cropMarks;
00057     bleedMarks = opt.bleedMarks;
00058     registrationMarks = opt.registrationMarks;
00059     colorMarks = opt.colorMarks;
00060     docInfoMarks = true;
00061 }
00062 
00063 ScPageOutput::ScPageOutput(ScribusDoc* doc, bool reloadImages, int resolution, bool useProfiles) 
00064             : m_marksOptions()
00065 {
00066     m_doc = doc;
00067     m_reloadImages = reloadImages;
00068     m_imageRes = resolution;
00069     m_useProfiles = useProfiles;
00070 }
00071 
00072 ScImage::RequestType ScPageOutput::translateImageModeToRequest( ScPainterExBase::ImageMode mode )
00073 {
00074     ScImage::RequestType value = ScImage::RGBData;
00075     if ( mode == ScPainterExBase::cmykImages )
00076         value = ScImage::CMYKData;
00077     else if ( mode == ScPainterExBase::rgbImages )
00078         value = ScImage::RGBData;
00079     else if ( mode == ScPainterExBase::rgbProofImages )
00080         value = ScImage::RGBProof;
00081     else if ( mode == ScPainterExBase::rawImages )
00082         value = ScImage::RawData;
00083     return value;
00084 }
00085 
00086 void ScPageOutput::DrawPage( Page* page, ScPainterExBase* painter)
00087 {
00088     int clipx = static_cast<int>(page->xOffset());
00089     int clipy = static_cast<int>(page->yOffset());
00090     int clipw = qRound(page->width());
00091     int cliph = qRound(page->height());
00092     DrawMasterItems(painter, page, QRect(clipx, clipy, clipw, cliph));
00093     DrawPageItems(painter, page, QRect(clipx, clipy, clipw, cliph));
00094     DrawMarks(page, painter, m_marksOptions);
00095 }
00096 
00097 void ScPageOutput::DrawMasterItems(ScPainterExBase *painter, Page *page, const QRect& clip)
00098 {
00099     QStack<PageItem*> groupStack;
00100     QStack<PageItem*> groupClips;
00101     if (!page->MPageNam.isEmpty())
00102     {
00103         Page* Mp = m_doc->MasterPages.at(m_doc->MasterNames[page->MPageNam]);
00104         if (page->FromMaster.count() != 0)
00105         {
00106             int Lnr;
00107             ScLayer ll;
00108             PageItem *currItem;
00109             ll.isViewable = false;
00110             ll.LNr = 0;
00111             Lnr = 0;
00112             uint layerCount = m_doc->layerCount();
00113             for (uint la = 0; la < layerCount; ++la)
00114             {
00115                 m_doc->Layers.levelToLayer(ll, Lnr);
00116                 bool pr = true;
00117                 if ( !ll.isPrintable )
00118                     pr = false;
00119                 if ((ll.isViewable) && (pr))
00120                 {
00121                     uint pageFromMasterCount=page->FromMaster.count();
00122                     for (uint a = 0; a < pageFromMasterCount; ++a)
00123                     {
00124                         currItem = page->FromMaster.at(a);
00125                         if (currItem->LayerNr != ll.LNr)
00126                             continue;
00127                         if ((currItem->OwnPage != -1) && (currItem->OwnPage != static_cast<int>(Mp->pageNr())))
00128                             continue;
00129                         if (!currItem->printEnabled())
00130                             continue;
00131                         if (currItem->isGroupControl)
00132                         {
00133                             painter->save();
00134                             groupClips.push(currItem);
00135                             groupStack.push(currItem->groupsLastItem);
00136                             continue;
00137                         }
00138                         int savedOwnPage = currItem->OwnPage;
00139                         double OldX = currItem->xPos();
00140                         double OldY = currItem->yPos();
00141                         double OldBX = currItem->BoundingX;
00142                         double OldBY = currItem->BoundingY;
00143                         currItem->OwnPage = page->pageNr();
00144                         if (!currItem->ChangedMasterItem)
00145                         {
00146                             currItem->moveBy(-Mp->xOffset() + page->xOffset(), -Mp->yOffset() + page->yOffset());
00147                             currItem->BoundingX = OldBX - Mp->xOffset() + page->xOffset();
00148                             currItem->BoundingY = OldBY - Mp->yOffset() + page->yOffset();
00149                         }
00150                         /*if (evSpon)
00151                             currItem->Dirty = true;*/
00152                         QRect oldR(currItem->getRedrawBounding(1.0));
00153                         if (clip.intersects(oldR))
00154                             DrawItem(currItem, painter, clip);
00155                         currItem->OwnPage = savedOwnPage;
00156                         if (!currItem->ChangedMasterItem)
00157                         {
00158                             currItem->setXPos(OldX);
00159                             currItem->setYPos(OldY);
00160                             currItem->BoundingX = OldBX;
00161                             currItem->BoundingY = OldBY;
00162                         }
00163                         if (groupStack.count() != 0)
00164                         {
00165                             while (currItem == groupStack.top())
00166                             {
00167                                 QMatrix mm;
00168                                 PageItem *tmpItem = groupClips.pop();
00169                                 FPointArray cl = tmpItem->PoLine.copy();
00170                                 mm.translate(tmpItem->xPos(), tmpItem->yPos());
00171                                 mm.rotate(tmpItem->rotation());
00172                                 cl.map( mm );
00173                                 painter->setupPolygon(&cl);
00174                                 painter->setClipPath();
00175                                 painter->restore();
00176                                 groupStack.pop();
00177                                 if (groupStack.count() == 0)
00178                                     break;
00179                             }
00180                         }
00181                     }
00182                     for (uint a = 0; a < pageFromMasterCount; ++a)
00183                     {
00184                         currItem = page->FromMaster.at(a);
00185                         if (currItem->LayerNr != ll.LNr)
00186                             continue;
00187                         if (!currItem->isTableItem)
00188                             continue;
00189                         if ((currItem->OwnPage != -1) && (currItem->OwnPage != static_cast<int>(Mp->pageNr())))
00190                             continue;
00191                         double OldX = currItem->xPos();
00192                         double OldY = currItem->yPos();
00193                         double OldBX = currItem->BoundingX;
00194                         double OldBY = currItem->BoundingY;
00195                         if (!currItem->ChangedMasterItem)
00196                         {
00197                             currItem->setXPos(OldX - Mp->xOffset() + page->xOffset());
00198                             currItem->setYPos(OldY - Mp->yOffset() + page->yOffset());
00199                             currItem->BoundingX = OldBX - Mp->xOffset() + page->xOffset();
00200                             currItem->BoundingY = OldBY - Mp->yOffset() + page->yOffset();
00201                         }
00202                         QRect oldR(currItem->getRedrawBounding(1.0));
00203                         if (clip.intersects(oldR))
00204                         {
00205                             painter->save();
00206                             painter->translate(currItem->xPos(), currItem->yPos());
00207                             painter->rotate(currItem->rotation());
00208                             if (currItem->lineColor() != CommonStrings::None)
00209                             {
00210                                 ScColorShade tmp( m_doc->PageColors[currItem->lineColor()], (int) currItem->lineShade());
00211                                 if ((currItem->TopLine) || (currItem->RightLine) || (currItem->BottomLine) || (currItem->LeftLine))
00212                                 {
00213                                     painter->setPen(tmp, currItem->lineWidth(), currItem->PLineArt, Qt::SquareCap, currItem->PLineJoin);
00214                                     if (currItem->TopLine)
00215                                         painter->drawLine(FPoint(0.0, 0.0), FPoint(currItem->width(), 0.0));
00216                                     if (currItem->RightLine)
00217                                         painter->drawLine(FPoint(currItem->width(), 0.0), FPoint(currItem->width(), currItem->height()));
00218                                     if (currItem->BottomLine)
00219                                         painter->drawLine(FPoint(currItem->width(), currItem->height()), FPoint(0.0, currItem->height()));
00220                                     if (currItem->LeftLine)
00221                                         painter->drawLine(FPoint(0.0, currItem->height()), FPoint(0.0, 0.0));
00222                                 }
00223                             }
00224                             painter->restore();
00225                         }
00226                         if (!currItem->ChangedMasterItem)
00227                         {
00228                             currItem->setXPos(OldX);
00229                             currItem->setYPos(OldY);
00230                             currItem->BoundingX = OldBX;
00231                             currItem->BoundingY = OldBY;
00232                         }
00233                     }
00234                 }
00235                 Lnr++;
00236             }
00237         }
00238     }
00239 }
00240 
00241 void ScPageOutput::DrawPageItems(ScPainterExBase *painter, Page *page, const QRect& clip)
00242 {
00243     //linkedFramesToShow.clear();
00244     QStack<PageItem*> groupStack;
00245     QStack<PageItem*> groupClips;
00246     if (m_doc->Items->count() != 0)
00247     {
00248         int Lnr=0;
00249         ScLayer ll;
00250         PageItem *currItem;
00251         ll.isViewable = false;
00252         ll.LNr = 0;
00253         uint layerCount = m_doc->layerCount();
00254         //int docCurrPageNo=static_cast<int>(m_doc->currentPageNumber());
00255         int docCurrPageNo=static_cast<int>(page->pageNr());
00256         for (uint la2 = 0; la2 < layerCount; ++la2)
00257         {
00258             m_doc->Layers.levelToLayer(ll, Lnr);
00259             bool pr = true;
00260             if (!ll.isPrintable)
00261                 pr = false;
00262             if ((ll.isViewable) && (pr))
00263             {
00264                 for (int it = 0; it < m_doc->Items->count(); ++it)
00265                 {
00266                     currItem = m_doc->Items->at(it);
00267                     if (currItem->LayerNr != ll.LNr)
00268                         continue;
00269                     if (!currItem->printEnabled())
00270                         continue;
00271                     if ((m_doc->masterPageMode()) && ((currItem->OwnPage != -1) && (currItem->OwnPage != docCurrPageNo)))
00272                         continue;
00273                     if (!m_doc->masterPageMode() && !currItem->OnMasterPage.isEmpty())
00274                     {
00275                         if (currItem->OnMasterPage != page->pageName())
00276                             continue;
00277                     }
00278                     if (currItem->isGroupControl)
00279                     {
00280                         painter->save();
00281                         groupClips.push(currItem);
00282                         groupStack.push(currItem->groupsLastItem);
00283                         continue;
00284                     }
00285                     QRect oldR(currItem->getRedrawBounding(1.0));
00286                     if (clip.intersects(oldR))
00287                     {
00288                         DrawItem( currItem, painter, clip );
00289                         if ((currItem->asTextFrame()) && ((currItem->nextInChain() != 0) || (currItem->prevInChain() != 0)))
00290                         {
00291                             PageItem *nextItem = currItem;
00292                             while (nextItem != 0)
00293                             {
00294                                 if (nextItem->prevInChain() != 0)
00295                                     nextItem = nextItem->prevInChain();
00296                                 else
00297                                     break;
00298                             }
00299                         }
00300                     }
00301                     if (groupStack.count() != 0)
00302                     {
00303                         while (currItem == groupStack.top())
00304                         {
00305                             QMatrix mm;
00306                             PageItem *tmpItem = groupClips.pop();
00307                             FPointArray cl = tmpItem->PoLine.copy();
00308                             mm.translate(tmpItem->xPos(), tmpItem->yPos());
00309                             mm.rotate(tmpItem->rotation());
00310                             cl.map( mm );
00311                             painter->setupPolygon(&cl);
00312                             painter->setClipPath();
00313                             painter->restore();
00314                             groupStack.pop();
00315                             if (groupStack.count() == 0)
00316                                 break;
00317                         }
00318                     }
00319                 }
00320                 for (int it = 0; it < m_doc->Items->count(); ++it)
00321                 {
00322                     currItem = m_doc->Items->at(it);
00323                     if (currItem->LayerNr != ll.LNr)
00324                         continue;
00325                     if (!currItem->isTableItem)
00326                         continue;
00327                     QRect oldR(currItem->getRedrawBounding(1.0));
00328                     if (clip.intersects(oldR))
00329                     {
00330                         painter->save();
00331                         painter->translate(currItem->xPos(), currItem->yPos());
00332                         painter->rotate(currItem->rotation());
00333                         if (currItem->lineColor() != CommonStrings::None)
00334                         {
00335                             ScColorShade tmp( m_doc->PageColors[currItem->lineColor()], (int) currItem->lineShade() );
00336                             if ((currItem->TopLine) || (currItem->RightLine) || (currItem->BottomLine) || (currItem->LeftLine))
00337                             {
00338                                 painter->setPen(tmp, currItem->lineWidth(), currItem->PLineArt, Qt::SquareCap, currItem->PLineJoin);
00339                                 if (currItem->TopLine)
00340                                     painter->drawLine(FPoint(0.0, 0.0), FPoint(currItem->width(), 0.0));
00341                                 if (currItem->RightLine)
00342                                     painter->drawLine(FPoint(currItem->width(), 0.0), FPoint(currItem->width(), currItem->height()));
00343                                 if (currItem->BottomLine)
00344                                     painter->drawLine(FPoint(currItem->width(), currItem->height()), FPoint(0.0, currItem->height()));
00345                                 if (currItem->LeftLine)
00346                                     painter->drawLine(FPoint(0.0, currItem->height()), FPoint(0.0, 0.0));
00347                             }
00348                         }
00349                         painter->restore();
00350                     }
00351                 }
00352             }
00353             Lnr++;
00354         }
00355     }
00356 }
00357 
00358 void ScPageOutput::DrawItem( PageItem* item, ScPainterExBase* painter, const QRect& clip )
00359 {
00360     DrawItem_Pre(item, painter);
00361     PageItem::ItemType itemType = item->itemType();
00362     if( itemType == PageItem::ImageFrame )
00363         DrawItem_ImageFrame( (PageItem_ImageFrame*) item, painter, clip);
00364     else if( itemType == PageItem::Line )
00365         DrawItem_Line( (PageItem_Line*) item, painter, clip);
00366     else if( itemType == PageItem::PathText )
00367         DrawItem_PathText(  (PageItem_PathText*) item, painter, clip);
00368     else if( itemType == PageItem::Polygon )
00369         DrawItem_Polygon( (PageItem_Polygon*) item, painter, clip);
00370     else if( itemType == PageItem::PolyLine )
00371         DrawItem_PolyLine( (PageItem_PolyLine*) item, painter, clip);
00372     else if( itemType == PageItem::TextFrame )
00373         DrawItem_TextFrame( (PageItem_TextFrame*) item, painter, clip);
00374     DrawItem_Post(item, painter);
00375 }
00376 
00377 void ScPageOutput::DrawItem_Pre( PageItem* item, ScPainterExBase* painter)
00378 {
00379     painter->save();
00380     if (!item->isEmbedded)
00381     {
00382         painter->translate( item->xPos(), item->yPos());
00383 //      painter->rotate(item->rotation());
00384     }
00385     painter->rotate(item->rotation());
00386     painter->setLineWidth(item->lineWidth());
00387     if (item->GrType == 8)
00388     {
00389         QString pat = item->pattern();
00390         if ((pat.isEmpty()) || (!m_doc->docPatterns.contains(pat)))
00391         {
00392             painter->m_fillGradient = VGradientEx(VGradientEx::linear);
00393             if (item->fillColor() != CommonStrings::None)
00394             {
00395                 painter->setBrush(ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()));
00396                 painter->setFillMode(ScPainterExBase::Solid);
00397             }
00398             else
00399                 painter->setFillMode(ScPainterExBase::None);
00400         }
00401         else
00402         {
00403             QMatrix patternTransform;
00404             ScPattern& pattern = m_doc->docPatterns[item->pattern()];
00405             double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation;
00406             item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation);
00407             patternTransform.translate(patternOffsetX, patternOffsetY);
00408             patternTransform.rotate(patternRotation);
00409             patternTransform.scale(pattern.scaleX, pattern.scaleY);
00410             patternTransform.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
00411             painter->setPattern(&pattern, patternTransform);
00412             painter->setFillMode(ScPainterExBase::Pattern);
00413         }
00414     }
00415     else if (item->GrType != 0)
00416     {
00417         painter->setFillMode(ScPainterExBase::Gradient);
00418         painter->m_fillGradient = VGradientEx(item->fill_gradient, *m_doc);
00419         QMatrix grm;
00420         grm.rotate(item->rotation());
00421         FPointArray gra;
00422         switch (item->GrType)
00423         {
00424             case 1:
00425             case 2:
00426             case 3:
00427             case 4:
00428             case 6:
00429                 gra.setPoints(2, item->GrStartX, item->GrStartY, item->GrEndX, item->GrEndY);
00430                 gra.map(grm);
00431                 painter->setGradient(VGradientEx::linear, gra.point(0), gra.point(1));
00432                 break;
00433             case 5:
00434             case 7:
00435                 gra.setPoints(2, item->GrStartX, item->GrStartY, item->GrEndX, item->GrEndY);
00436                 painter->setGradient(VGradientEx::radial, gra.point(0), gra.point(1), gra.point(0));
00437                 break;
00438         }
00439     }
00440     else
00441     {
00442         painter->m_fillGradient = VGradientEx(VGradientEx::linear);
00443         if (item->fillColor() != CommonStrings::None)
00444         {
00445             painter->setBrush( ScColorShade(m_doc->PageColors[item->fillColor()], (int) item->fillShade()) );
00446             painter->setFillMode(ScPainterExBase::Solid);
00447         }
00448         else
00449             painter->setFillMode(ScPainterExBase::None);
00450     }
00451     if (item->lineColor() != CommonStrings::None)
00452     {
00453         if ((item->lineWidth() == 0) && !item->asLine())
00454             painter->setLineWidth(0);
00455         else
00456         {
00457             ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
00458             painter->setPen( tmp , item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
00459             if (item->DashValues.count() != 0)
00460                 painter->setDash(item->DashValues, item->DashOffset);
00461         }
00462     }
00463     else
00464         painter->setLineWidth(0);
00465     painter->setBrushOpacity(1.0 - item->fillTransparency());
00466     painter->setPenOpacity(1.0 - item->lineTransparency());
00467     painter->setFillRule(item->fillRule);
00468 }
00469 
00470 void ScPageOutput::DrawItem_Post( PageItem* item, ScPainterExBase* painter )
00471 {
00472     bool doStroke=true;
00473     if ( item->itemType() == PageItem::PathText || item->itemType() == PageItem::PolyLine || item->itemType() == PageItem::Line )
00474         doStroke=false;
00475     if ((doStroke))
00476     {
00477         if (item->lineColor() != CommonStrings::None)
00478         {
00479             ScColorShade tmp(m_doc->PageColors[item->lineColor()], (int) item->lineShade());
00480             painter->setPen(tmp, item->lineWidth(), item->PLineArt, item->PLineEnd, item->PLineJoin);
00481             if (item->DashValues.count() != 0)
00482                 painter->setDash(item->DashValues, item->DashOffset);
00483         }
00484         else
00485             painter->setLineWidth(0);
00486         if (!item->isTableItem)
00487         {
00488             painter->setupPolygon(&item->PoLine);
00489             if (item->NamedLStyle.isEmpty())
00490                 painter->strokePath();
00491             else
00492             {
00493                 multiLine ml = m_doc->MLineStyles[item->NamedLStyle];
00494                 for (int it = ml.size()-1; it > -1; it--)
00495                 {
00496                     const SingleLine& sl = ml[it];
00497                     if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
00498                     {
00499                         ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
00500                         painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
00501                                 static_cast<Qt::PenCapStyle>(sl.LineEnd),
00502                                 static_cast<Qt::PenJoinStyle>(sl.LineJoin));
00503                         painter->strokePath();
00504                     }
00505                 }
00506             }
00507         }
00508     }
00509 //  item->Tinput = false;
00510     painter->restore();
00511 }
00512 
00513 void ScPageOutput::DrawGlyphs(PageItem* item, ScPainterExBase *painter, const CharStyle& style, GlyphLayout& glyphs, const QRect& clip)
00514 {
00515     uint glyph = glyphs.glyph;
00516     if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode())) // NBSPACE
00517         glyph = style.font().char2CMap(QChar(' '));
00518     else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode())) // NBHYPHEN
00519         glyph = style.font().char2CMap(QChar('-'));
00520     
00521     if (glyph >= ScFace::CONTROL_GLYPHS)
00522     {
00523         if (glyphs.more)
00524         {
00525             painter->translate(glyphs.xadvance, 0);
00526             DrawGlyphs(item, painter, style, *glyphs.more, clip);
00527         }
00528         return;
00529     }
00530     
00531     //if (style.font().canRender(QChar(glyph)))
00532     {
00533         QMatrix chma, chma2, chma3, chma4, chma5, chma6;
00534         chma.scale(glyphs.scaleH * style.fontSize() / 100.00, glyphs.scaleV * style.fontSize() / 100.0);
00535 //      qDebug(QString("glyphscale: %1 %2").arg(glyphs.scaleH).arg(glyphs.scaleV));
00536         FPointArray gly = style.font().glyphOutline(glyph);
00537         // Do underlining first so you can get typographically correct
00538         // underlines when drawing a white outline
00539         if ((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && (glyph != style.font().char2CMap(QChar(' ')))))
00540         {
00541             double st, lw;
00542             if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
00543             {
00544                 if (style.underlineOffset() != -1)
00545                     st = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
00546                 else
00547                     st = style.font().underlinePos(style.fontSize() / 10.0);
00548                 if (style.underlineWidth() != -1)
00549                     lw = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
00550                 else
00551                     lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
00552             }
00553             else
00554             {
00555                 st = style.font().underlinePos(style.fontSize() / 10.0);
00556                 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
00557             }
00558             if (style.baselineOffset() != 0)
00559                 st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
00560             ScColorShade tmpPen = painter->pen();
00561             painter->setPen(painter->brush());
00562             painter->setLineWidth(lw);
00563             if (style.effects() & ScStyle_Subscript)
00564                 painter->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
00565             else
00566                 painter->drawLine(FPoint(glyphs.xoffset, -st), FPoint(glyphs.xoffset + glyphs.xadvance, -st));
00567             painter->setPen(tmpPen);
00568         }
00569         if (gly.size() > 3)
00570         {
00571             painter->save();
00572             painter->translate(glyphs.xoffset, glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV));
00573             if (item->reversed())
00574             {
00575                 painter->scale(-1, 1);
00576                 painter->translate(-glyphs.xadvance, 0);
00577             }
00578             if (style.baselineOffset() != 0)
00579                 painter->translate(0, -(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0));
00580             double glxSc = glyphs.scaleH * style.fontSize() / 100.00;
00581             double glySc = glyphs.scaleV * style.fontSize() / 100.0;
00582             painter->scale(glxSc, glySc);
00583             painter->setFillMode(ScPainterExBase::Solid);
00584             bool fr = painter->fillRule();
00585             painter->setFillRule(false);
00586             painter->setupTextPolygon(&gly);
00587             if (glyph == 0)
00588             {
00589                 ScColorShade tmp(PrefsManager::instance()->appPrefs.DControlCharColor, 100);
00590                 painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
00591                 painter->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() * 2 / 10000.0);
00592                 painter->strokePath();
00593             }
00594             else if ((style.font().isStroked()) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
00595             {
00596                 ScColorShade tmp = painter->brush();
00597                 painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
00598                 painter->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0);
00599                 painter->strokePath();
00600             }
00601             else
00602             {
00603                 if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
00604                 {
00605                     painter->save();
00606                     painter->translate((style.fontSize() * glyphs.scaleH * style.shadowXOffset() / 10000.0) / glxSc, -(style.fontSize() * glyphs.scaleV * style.shadowYOffset() / 10000.0) / glySc);
00607                     ScColorShade tmp = painter->brush();
00608                     painter->setBrush(painter->pen());
00609                     painter->setupTextPolygon(&gly);
00610                     FillPath(item, painter, clip);
00611                     painter->setBrush(tmp);
00612                     painter->restore();
00613                     painter->setupTextPolygon(&gly);
00614                 }
00615                 if (style.fillColor() != CommonStrings::None)
00616                     FillPath(item, painter, clip);
00617                 if ((style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
00618                 {
00619                     painter->setLineWidth((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) / glySc);
00620                     painter->strokePath();
00621                 }
00622             }
00623             painter->setFillRule(fr);
00624             painter->restore();
00625         }
00626         if (style.effects() & ScStyle_Strikethrough)
00627         {
00628             double st, lw;
00629             if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
00630             {
00631                 if (style.strikethruOffset() != -1)
00632                     st = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
00633                 else
00634                     st = style.font().strikeoutPos(style.fontSize() / 10.0);
00635                 if (style.strikethruWidth() != -1)
00636                     lw = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
00637                 else
00638                     lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
00639             }
00640             else
00641             {
00642                 st = style.font().strikeoutPos(style.fontSize() / 10.0);
00643                 lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
00644             }
00645             if (style.baselineOffset() != 0)
00646                 st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
00647             painter->setPen(painter->brush());
00648             painter->setLineWidth(lw);
00649             painter->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
00650         }
00651     }
00652     /*else
00653     {
00654         painter->setLineWidth(1);
00655         painter->setPen(ScColorShade(Qt::red, 100));
00656         painter->setBrush(ScColorShade(Qt::red, 100));
00657         painter->setFillMode(1);
00658         painter->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
00659     }*/
00660     if (glyphs.more)
00661     {
00662         painter->translate(glyphs.xadvance, 0);
00663         DrawGlyphs(item, painter, style, *glyphs.more, clip);
00664     }
00665 }
00666 
00667 void ScPageOutput::DrawItem_Embedded( PageItem* item, ScPainterExBase *p, const QRect& clip, const CharStyle& style, PageItem* cembedded)
00668 {
00669     if (!cembedded)
00670         return;
00671     QList<PageItem*> emG;
00672     QStack<PageItem*> groupStack;
00673     emG.clear();
00674     emG.append(cembedded);
00675     if (cembedded->Groups.count() != 0)
00676     {
00677         for (int ga=0; ga < m_doc->FrameItems.count(); ++ga)
00678         {
00679             if (m_doc->FrameItems.at(ga)->Groups.count() != 0)
00680             {
00681                 if (m_doc->FrameItems.at(ga)->Groups.top() == cembedded->Groups.top())
00682                 {
00683                     if (m_doc->FrameItems.at(ga)->ItemNr != cembedded->ItemNr)
00684                     {
00685                         if (!emG.contains(m_doc->FrameItems.at(ga)))
00686                             emG.append(m_doc->FrameItems.at(ga));
00687                     }
00688                 }
00689             }
00690         }
00691     }
00692     for (int em = 0; em < emG.count(); ++em)
00693     {
00694         PageItem* embedded = emG.at(em);
00695         p->save();
00696         embedded->setXPos( item->xPos() + embedded->gXpos );
00697         embedded->setYPos( item->yPos() - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos );
00698         p->translate((embedded->gXpos * (style.scaleH() / 1000.0)), ( - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
00699         if (style.baselineOffset() != 0)
00700         {
00701             p->translate(0, -embedded->gHeight * (style.baselineOffset() / 1000.0));
00702             embedded->setYPos( embedded->yPos() - embedded->gHeight * (style.baselineOffset() / 1000.0) );
00703         }
00704         p->scale(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
00705         if (embedded->isGroupControl)
00706         {
00707             p->restore();
00708             p->save();
00709             FPointArray cl = embedded->PoLine.copy();
00710             QMatrix mm;
00711             mm.translate(embedded->xPos() - item->xPos(), embedded->yPos() - item->yPos());
00712             mm.rotate(embedded->rotation());
00713             cl.map( mm );
00714             groupStack.push(embedded->groupsLastItem);
00715             continue;
00716         }
00717         double pws = embedded->m_lineWidth;
00718         DrawItem_Pre(embedded, p);
00719         switch(embedded->itemType())
00720         {
00721             case PageItem::ImageFrame:
00722             case PageItem::LatexFrame:
00723             case PageItem::TextFrame:
00724             case PageItem::Polygon:
00725             case PageItem::PathText:
00726                 DrawItem(embedded, p, clip);
00727                 break;
00728             case PageItem::Line:
00729             case PageItem::PolyLine:
00730                 embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
00731                 DrawItem(embedded, p, clip);
00732                 break;
00733             default:
00734                 break;
00735         }
00736         embedded->m_lineWidth = pws * qMin(style.scaleH() / 1000.0, style.scaleV() / 1000.0);
00737         DrawItem_Post(embedded, p);
00738         p->restore();
00739         if (groupStack.count() != 0)
00740         {
00741             while (embedded == groupStack.top())
00742             {
00743                 p->restore();
00744                 groupStack.pop();
00745                 if (groupStack.count() == 0)
00746                     break;
00747             }
00748         }
00749         embedded->m_lineWidth = pws;
00750     }
00751 }
00752 
00753 void ScPageOutput::DrawPattern( PageItem* item, ScPainterExBase* painter, const QRect& clip)
00754 {
00755     double x1, x2, y1, y2;
00756     ScPattern& pattern = m_doc->docPatterns[item->pattern()];
00757     double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation;
00758     item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation);
00759 
00760     // Compute pattern tansformation matrix and its inverse for converting pattern coordinates
00761     // to pageitem coordinates 
00762     QMatrix matrix, invMat;
00763     matrix.translate(patternOffsetX, patternOffsetY);
00764     matrix.rotate(patternRotation);
00765     matrix.scale(pattern.scaleX, pattern.scaleY);
00766     matrix.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
00767     invMat.scale((patternScaleX != 0) ? (100 /pattern