00001
00002
00003
00004
00005
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
00151
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
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
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
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
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()))
00517 glyph = style.font().char2CMap(QChar(' '));
00518 else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
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
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
00536 FPointArray gly = style.font().glyphOutline(glyph);
00537
00538
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
00653
00654
00655
00656
00657
00658
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
00761
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