File indexing completed on 2024-04-21 04:32:13
0001 /* 0002 * Copyright (C) 2010-2015 by Stephen Allewell 0003 * steve.allewell@gmail.com 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 */ 0010 0011 #include "Renderer.h" 0012 0013 #include <QPaintEngine> 0014 #include <QPainter> 0015 #include <QPen> 0016 #include <QWidget> 0017 0018 #include "Document.h" 0019 #include "DocumentFloss.h" 0020 #include "Stitch.h" 0021 #include "Symbol.h" 0022 #include "SymbolLibrary.h" 0023 #include "SymbolManager.h" 0024 0025 class RendererData : public QSharedData 0026 { 0027 public: 0028 RendererData(); 0029 RendererData(const RendererData &); 0030 0031 friend class Renderer; 0032 0033 private: 0034 int m_cellHorizontalGrouping; 0035 int m_cellVerticalGrouping; 0036 0037 double m_thinLineWidth; 0038 double m_thickLineWidth; 0039 0040 QColor m_thinLineColor; 0041 QColor m_thickLineColor; 0042 0043 Configuration::EnumRenderer_RenderStitchesAs::type m_renderStitchesAs; 0044 Configuration::EnumRenderer_RenderBackstitchesAs::type m_renderBackstitchesAs; 0045 Configuration::EnumRenderer_RenderKnotsAs::type m_renderKnotsAs; 0046 0047 QPainter *m_painter; 0048 0049 Document *m_document; 0050 Pattern *m_pattern; 0051 SymbolLibrary *m_symbolLibrary; 0052 0053 int m_highlight; 0054 0055 QPointF m_topLeft; 0056 QPointF m_topRight; 0057 QPointF m_bottomLeft; 0058 QPointF m_bottomRight; 0059 QPointF m_center; 0060 QPointF m_centerTop; 0061 QPointF m_centerLeft; 0062 QPointF m_centerRight; 0063 QPointF m_centerBottom; 0064 0065 QRectF m_renderCell; 0066 QRectF m_renderTLCell; 0067 QRectF m_renderTL3Cell; 0068 QRectF m_renderTRCell; 0069 QRectF m_renderTR3Cell; 0070 QRectF m_renderBLCell; 0071 QRectF m_renderBL3Cell; 0072 QRectF m_renderBRCell; 0073 QRectF m_renderBR3Cell; 0074 0075 QPolygonF m_renderTLQ; 0076 QPolygonF m_renderTRQ; 0077 QPolygonF m_renderBLQ; 0078 QPolygonF m_renderBRQ; 0079 0080 QPolygonF m_renderBLTRH; 0081 QPolygonF m_renderTLBRH; 0082 0083 QPolygonF m_renderTL3Q; 0084 QPolygonF m_renderTR3Q; 0085 QPolygonF m_renderBL3Q; 0086 QPolygonF m_renderBR3Q; 0087 }; 0088 0089 RendererData::RendererData() 0090 : QSharedData() 0091 , m_cellHorizontalGrouping(Configuration::editor_CellHorizontalGrouping()) 0092 , m_cellVerticalGrouping(Configuration::editor_CellVerticalGrouping()) 0093 , m_thinLineColor(Configuration::editor_ThinLineColor()) 0094 , m_thickLineColor(Configuration::editor_ThickLineColor()) 0095 , m_renderStitchesAs(Configuration::renderer_RenderStitchesAs()) 0096 , m_renderBackstitchesAs(Configuration::renderer_RenderBackstitchesAs()) 0097 , m_renderKnotsAs(Configuration::renderer_RenderKnotsAs()) 0098 , m_painter(nullptr) 0099 , m_document(nullptr) 0100 , m_pattern(nullptr) 0101 , m_symbolLibrary(nullptr) 0102 { 0103 m_topLeft = QPointF(0.0, 0.0); 0104 m_topRight = QPointF(1.0, 0.0); 0105 m_bottomLeft = QPointF(0.0, 1.0); 0106 m_bottomRight = QPointF(1.0, 1.0); 0107 m_center = QPointF(0.5, 0.5); 0108 m_centerTop = QPointF(0.5, 0.0); 0109 m_centerLeft = QPointF(0.0, 0.5); 0110 m_centerRight = QPointF(1.0, 0.5); 0111 m_centerBottom = QPointF(0.5, 1.0); 0112 0113 double oneThird = 1.0 / 3.0; 0114 double twoThird = 2.0 / 3.0; 0115 0116 m_renderCell = QRectF(m_topLeft, m_bottomRight); 0117 m_renderTLCell = QRectF(m_topLeft, m_center); 0118 m_renderTL3Cell = QRectF(m_topLeft, QSize(twoThird, twoThird)); 0119 m_renderTRCell = QRectF(m_centerTop, m_centerRight); 0120 m_renderTR3Cell = QRectF(oneThird, 0, twoThird, twoThird); 0121 m_renderBLCell = QRectF(m_centerLeft, m_centerBottom); 0122 m_renderBL3Cell = QRectF(0, oneThird, twoThird, twoThird); 0123 m_renderBRCell = QRectF(m_center, m_bottomRight); 0124 m_renderBR3Cell = QRectF(oneThird, oneThird, twoThird, twoThird); 0125 0126 m_renderTLQ << m_topLeft << m_centerTop << m_centerLeft; 0127 m_renderTRQ << m_centerTop << m_topRight << m_centerRight; 0128 m_renderBLQ << m_centerLeft << m_centerBottom << m_bottomLeft; 0129 m_renderBRQ << m_centerRight << m_bottomRight << m_centerBottom; 0130 m_renderBLTRH << m_bottomLeft << m_centerLeft << m_centerTop << m_topRight << m_centerRight << m_centerBottom; 0131 m_renderTLBRH << m_topLeft << m_centerTop << m_centerRight << m_bottomRight << m_centerBottom << m_centerLeft; 0132 m_renderTL3Q << m_topLeft << m_topRight << m_centerRight << m_centerBottom << m_bottomLeft; 0133 m_renderTR3Q << m_topLeft << m_topRight << m_bottomRight << m_centerBottom << m_centerLeft; 0134 m_renderBL3Q << m_topLeft << m_centerTop << m_centerRight << m_bottomRight << m_bottomLeft; 0135 m_renderBR3Q << m_centerTop << m_topRight << m_bottomRight << m_bottomLeft << m_centerLeft; 0136 } 0137 0138 RendererData::RendererData(const RendererData &other) 0139 : QSharedData(other) 0140 , m_cellHorizontalGrouping(other.m_cellHorizontalGrouping) 0141 , m_cellVerticalGrouping(other.m_cellVerticalGrouping) 0142 , m_thinLineWidth(other.m_thinLineWidth) 0143 , m_thickLineWidth(other.m_thickLineWidth) 0144 , m_thinLineColor(other.m_thinLineColor) 0145 , m_thickLineColor(other.m_thickLineColor) 0146 , m_renderStitchesAs(other.m_renderStitchesAs) 0147 , m_renderBackstitchesAs(other.m_renderBackstitchesAs) 0148 , m_renderKnotsAs(other.m_renderKnotsAs) 0149 , m_document(other.m_document) 0150 , m_pattern(other.m_pattern) 0151 , m_symbolLibrary(other.m_symbolLibrary) 0152 , m_topLeft(other.m_topLeft) 0153 , m_topRight(other.m_topRight) 0154 , m_bottomLeft(other.m_bottomLeft) 0155 , m_bottomRight(other.m_bottomRight) 0156 , m_center(other.m_center) 0157 , m_renderCell(other.m_renderCell) 0158 , m_renderTLCell(other.m_renderTLCell) 0159 , m_renderTL3Cell(other.m_renderTL3Cell) 0160 , m_renderTRCell(other.m_renderTRCell) 0161 , m_renderTR3Cell(other.m_renderTR3Cell) 0162 , m_renderBLCell(other.m_renderBLCell) 0163 , m_renderBL3Cell(other.m_renderBL3Cell) 0164 , m_renderBRCell(other.m_renderBRCell) 0165 , m_renderBR3Cell(other.m_renderBR3Cell) 0166 , m_renderTLQ(other.m_renderTLQ) 0167 , m_renderTRQ(other.m_renderTRQ) 0168 , m_renderBLQ(other.m_renderBLQ) 0169 , m_renderBRQ(other.m_renderBRQ) 0170 , m_renderBLTRH(other.m_renderBLTRH) 0171 , m_renderTLBRH(other.m_renderTLBRH) 0172 , m_renderTL3Q(other.m_renderTL3Q) 0173 , m_renderTR3Q(other.m_renderTR3Q) 0174 , m_renderBL3Q(other.m_renderBL3Q) 0175 , m_renderBR3Q(other.m_renderBR3Q) 0176 { 0177 } 0178 0179 const Renderer::renderStitchCallPointer Renderer::renderStitchCallPointers[] = { 0180 &Renderer::renderStitchesAsStitches, 0181 &Renderer::renderStitchesAsBlackWhiteSymbols, 0182 &Renderer::renderStitchesAsColorSymbols, 0183 &Renderer::renderStitchesAsColorBlocks, 0184 &Renderer::renderStitchesAsColorBlocksSymbols, 0185 }; 0186 0187 const Renderer::renderBackstitchCallPointer Renderer::renderBackstitchCallPointers[] = { 0188 &Renderer::renderBackstitchesAsColorLines, 0189 &Renderer::renderBackstitchesAsBlackWhiteSymbols, 0190 }; 0191 0192 const Renderer::renderKnotCallPointer Renderer::renderKnotCallPointers[] = { 0193 &Renderer::renderKnotsAsColorBlocks, 0194 &Renderer::renderKnotsAsColorBlocksSymbols, 0195 &Renderer::renderKnotsAsColorSymbols, 0196 &Renderer::renderKnotsAsBlackWhiteSymbols, 0197 }; 0198 0199 Renderer::Renderer() 0200 : d(new RendererData) 0201 { 0202 setGridLineWidths(Configuration::editor_ThinLineWidth(), Configuration::editor_ThickLineWidth()); 0203 } 0204 0205 Renderer::Renderer(const Renderer &other) 0206 : d(other.d) 0207 { 0208 } 0209 0210 Renderer::~Renderer() 0211 { 0212 } 0213 0214 void Renderer::setCellGrouping(int cellHorizontalGrouping, int cellVerticalGrouping) 0215 { 0216 d->m_cellHorizontalGrouping = cellHorizontalGrouping; 0217 d->m_cellVerticalGrouping = cellVerticalGrouping; 0218 } 0219 0220 void Renderer::setGridLineWidths(double thinLineWidth, double thickLineWidth) 0221 { 0222 thinLineWidth /= 100; 0223 thickLineWidth /= 100; 0224 0225 if (thinLineWidth == 0.0) { 0226 thinLineWidth = 0.025; 0227 } 0228 0229 if (thickLineWidth == 0.0) { 0230 thickLineWidth = 0.15; 0231 } 0232 0233 d->m_thinLineWidth = thinLineWidth; 0234 d->m_thickLineWidth = thickLineWidth; 0235 } 0236 0237 void Renderer::setGridLineColors(QColor thinLineColor, QColor thickLineColor) 0238 { 0239 d->m_thinLineColor = thinLineColor; 0240 d->m_thickLineColor = thickLineColor; 0241 } 0242 0243 void Renderer::setRenderStitchesAs(Configuration::EnumRenderer_RenderStitchesAs::type renderStitchesAs) 0244 { 0245 d->m_renderStitchesAs = renderStitchesAs; 0246 } 0247 0248 void Renderer::setRenderBackstitchesAs(Configuration::EnumRenderer_RenderBackstitchesAs::type renderBackstitchesAs) 0249 { 0250 d->m_renderBackstitchesAs = renderBackstitchesAs; 0251 } 0252 0253 void Renderer::setRenderKnotsAs(Configuration::EnumRenderer_RenderKnotsAs::type renderKnotsAs) 0254 { 0255 d->m_renderKnotsAs = renderKnotsAs; 0256 } 0257 0258 void Renderer::render(QPainter *painter, 0259 Pattern *pattern, 0260 QRect updateCells, 0261 bool renderGrid, 0262 bool renderStitches, 0263 bool renderBackstitches, 0264 bool renderKnots, 0265 int colorHighlight) 0266 { 0267 updateCells &= painter->window(); 0268 0269 painter->save(); 0270 0271 d->m_painter = painter; 0272 d->m_pattern = pattern; 0273 d->m_symbolLibrary = SymbolManager::library(pattern->palette().symbolLibrary()); 0274 d->m_highlight = colorHighlight; 0275 0276 int patternLeft = updateCells.left(); 0277 int patternRight = updateCells.right(); 0278 int patternTop = updateCells.top(); 0279 int patternBottom = updateCells.bottom(); 0280 int patternWidth = updateCells.width(); 0281 int patternHeight = updateCells.height(); 0282 0283 if (renderGrid) { 0284 QPen thickPen(d->m_thickLineColor); 0285 QPen thinPen(d->m_thinLineColor); 0286 thickPen.setWidthF(d->m_thickLineWidth); 0287 thinPen.setWidthF(d->m_thinLineWidth); 0288 0289 for (int y = patternTop; y <= patternTop + patternHeight; ++y) { 0290 painter->setPen((y % d->m_cellVerticalGrouping) ? thinPen : thickPen); 0291 painter->drawLine(patternLeft, y, patternLeft + patternWidth, y); 0292 } 0293 0294 for (int x = patternLeft; x <= patternLeft + patternWidth; ++x) { 0295 painter->setPen((x % d->m_cellHorizontalGrouping) ? thinPen : thickPen); 0296 painter->drawLine(x, patternTop, x, patternTop + patternHeight); 0297 } 0298 } 0299 0300 if (renderStitches) { 0301 QTransform transform = painter->transform(); 0302 0303 for (int y = patternTop; y <= patternBottom; ++y) { 0304 for (int x = patternLeft; x <= patternRight; ++x) { 0305 if (StitchQueue *queue = pattern->stitches().stitchQueueAt(QPoint(x, y))) { 0306 painter->translate(x, y); 0307 (this->*renderStitchCallPointers[d->m_renderStitchesAs])(queue); 0308 painter->setTransform(transform); 0309 } 0310 } 0311 } 0312 } 0313 0314 if (renderBackstitches) { 0315 QList<Backstitch *> backstitches = pattern->stitches().backstitches(); 0316 0317 for (int i = 0; i < backstitches.count(); ++i) { 0318 (this->*renderBackstitchCallPointers[d->m_renderBackstitchesAs])(backstitches.at(i)); 0319 } 0320 } 0321 0322 if (renderKnots) { 0323 QList<Knot *> knots = pattern->stitches().knots(); 0324 0325 for (int i = 0; i < knots.count(); ++i) { 0326 (this->*renderKnotCallPointers[d->m_renderKnotsAs])(knots.at(i)); 0327 } 0328 } 0329 0330 painter->restore(); 0331 } 0332 0333 void Renderer::renderStitchesAsStitches(StitchQueue *stitchQueue) 0334 { 0335 QPen pen(Qt::lightGray, 0, Qt::SolidLine, Qt::RoundCap); 0336 0337 int i = stitchQueue->count(); 0338 0339 while (i) { 0340 Stitch *stitch = stitchQueue->at(--i); 0341 DocumentFloss *documentFloss = d->m_pattern->palette().flosses().value(stitch->colorIndex); 0342 0343 if ((d->m_highlight == -1) || (stitch->colorIndex == d->m_highlight)) { 0344 pen.setColor(documentFloss->flossColor()); 0345 pen.setWidthF(documentFloss->stitchStrands() / 10.0); 0346 } else { 0347 pen.setColor(Qt::lightGray); 0348 pen.setWidthF(0); 0349 } 0350 0351 d->m_painter->setPen(pen); 0352 0353 switch (stitch->type) { 0354 case Stitch::Delete: 0355 break; 0356 0357 case Stitch::TLQtr: 0358 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0359 break; 0360 0361 case Stitch::TRQtr: 0362 d->m_painter->drawLine(d->m_topRight, d->m_center); 0363 break; 0364 0365 case Stitch::BLQtr: 0366 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0367 break; 0368 0369 case Stitch::BTHalf: 0370 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0371 break; 0372 0373 case Stitch::TL3Qtr: 0374 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0375 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0376 break; 0377 0378 case Stitch::BRQtr: 0379 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0380 break; 0381 0382 case Stitch::TBHalf: 0383 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0384 break; 0385 0386 case Stitch::TR3Qtr: 0387 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0388 d->m_painter->drawLine(d->m_topRight, d->m_center); 0389 break; 0390 0391 case Stitch::BL3Qtr: 0392 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0393 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0394 break; 0395 0396 case Stitch::BR3Qtr: 0397 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0398 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0399 break; 0400 0401 case Stitch::Full: 0402 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0403 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0404 break; 0405 0406 case Stitch::TLSmallHalf: 0407 d->m_painter->drawLine(d->m_centerLeft, d->m_centerTop); 0408 break; 0409 0410 case Stitch::TRSmallHalf: 0411 d->m_painter->drawLine(d->m_centerTop, d->m_centerRight); 0412 break; 0413 0414 case Stitch::BLSmallHalf: 0415 d->m_painter->drawLine(d->m_centerLeft, d->m_centerBottom); 0416 break; 0417 0418 case Stitch::BRSmallHalf: 0419 d->m_painter->drawLine(d->m_centerBottom, d->m_centerRight); 0420 break; 0421 0422 case Stitch::TLSmallFull: 0423 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0424 d->m_painter->drawLine(d->m_centerLeft, d->m_centerTop); 0425 break; 0426 0427 case Stitch::TRSmallFull: 0428 d->m_painter->drawLine(d->m_centerTop, d->m_centerRight); 0429 d->m_painter->drawLine(d->m_center, d->m_topRight); 0430 break; 0431 0432 case Stitch::BLSmallFull: 0433 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0434 d->m_painter->drawLine(d->m_centerLeft, d->m_centerBottom); 0435 break; 0436 0437 case Stitch::BRSmallFull: 0438 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0439 d->m_painter->drawLine(d->m_centerBottom, d->m_centerRight); 0440 break; 0441 0442 case Stitch::FrenchKnot: 0443 break; 0444 } 0445 } 0446 } 0447 0448 void Renderer::renderStitchesAsBlackWhiteSymbols(StitchQueue *stitchQueue) 0449 { 0450 int i = stitchQueue->count(); 0451 0452 while (i) { 0453 Stitch *stitch = stitchQueue->at(--i); 0454 DocumentFloss *documentFloss = d->m_pattern->palette().flosses().value(stitch->colorIndex); 0455 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0456 0457 QPen symbolPen = symbol.pen(); 0458 QBrush symbolBrush = symbol.brush(); 0459 0460 if ((d->m_highlight == -1) || (stitch->colorIndex == d->m_highlight)) { 0461 // the symbolPen and symbolBrush are already set up as black at this point 0462 } else { 0463 symbolPen.setColor(Qt::lightGray); 0464 symbolBrush.setColor(Qt::lightGray); 0465 } 0466 0467 d->m_painter->setPen(symbolPen); 0468 d->m_painter->setBrush(symbolBrush); 0469 0470 d->m_painter->drawPath(symbol.path(stitch->type)); 0471 0472 if (Configuration::renderer_RenderStitchHints()) { 0473 renderStitchHints(stitch); 0474 } 0475 } 0476 } 0477 0478 void Renderer::renderStitchesAsColorSymbols(StitchQueue *stitchQueue) 0479 { 0480 int i = stitchQueue->count(); 0481 0482 while (i) { 0483 Stitch *stitch = stitchQueue->at(--i); 0484 DocumentFloss *documentFloss = d->m_pattern->palette().flosses().value(stitch->colorIndex); 0485 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0486 0487 QPen symbolPen = symbol.pen(); 0488 QBrush symbolBrush = symbol.brush(); 0489 0490 if ((d->m_highlight == -1) || (stitch->colorIndex == d->m_highlight)) { 0491 symbolPen.setColor(documentFloss->flossColor()); 0492 symbolBrush.setColor(documentFloss->flossColor()); 0493 } else { 0494 symbolPen.setColor(Qt::lightGray); 0495 symbolBrush.setColor(Qt::lightGray); 0496 } 0497 0498 d->m_painter->setPen(symbolPen); 0499 d->m_painter->setBrush(symbolBrush); 0500 0501 d->m_painter->drawPath(symbol.path(stitch->type)); 0502 0503 if (Configuration::renderer_RenderStitchHints()) { 0504 renderStitchHints(stitch); 0505 } 0506 } 0507 } 0508 0509 void Renderer::renderStitchesAsColorBlocks(StitchQueue *stitchQueue) 0510 { 0511 QBrush blockBrush(Qt::SolidPattern); 0512 0513 int i = stitchQueue->count(); 0514 0515 while (i) { 0516 Stitch *stitch = stitchQueue->at(--i); 0517 DocumentFloss *documentFloss = d->m_pattern->palette().flosses().value(stitch->colorIndex); 0518 0519 if ((d->m_highlight == -1) || (stitch->colorIndex == d->m_highlight)) { 0520 blockBrush.setColor(documentFloss->flossColor()); 0521 } else { 0522 blockBrush.setColor(Qt::lightGray); 0523 } 0524 0525 d->m_painter->setPen(Qt::NoPen); 0526 d->m_painter->setBrush(blockBrush); 0527 0528 switch (stitch->type) { 0529 case Stitch::Delete: 0530 break; 0531 0532 case Stitch::TLQtr: 0533 d->m_painter->drawPolygon(d->m_renderTLQ); 0534 break; 0535 0536 case Stitch::TRQtr: 0537 d->m_painter->drawPolygon(d->m_renderTRQ); 0538 break; 0539 0540 case Stitch::BLQtr: 0541 d->m_painter->drawPolygon(d->m_renderBLQ); 0542 break; 0543 0544 case Stitch::BTHalf: 0545 d->m_painter->drawPolygon(d->m_renderBLTRH); 0546 break; 0547 0548 case Stitch::TL3Qtr: 0549 d->m_painter->drawPolygon(d->m_renderTL3Q); 0550 break; 0551 0552 case Stitch::BRQtr: 0553 d->m_painter->drawPolygon(d->m_renderBRQ); 0554 break; 0555 0556 case Stitch::TBHalf: 0557 d->m_painter->drawPolygon(d->m_renderTLBRH); 0558 break; 0559 0560 case Stitch::TR3Qtr: 0561 d->m_painter->drawPolygon(d->m_renderTR3Q); 0562 break; 0563 0564 case Stitch::BL3Qtr: 0565 d->m_painter->drawPolygon(d->m_renderBL3Q); 0566 break; 0567 0568 case Stitch::BR3Qtr: 0569 d->m_painter->drawPolygon(d->m_renderBR3Q); 0570 break; 0571 0572 case Stitch::Full: 0573 d->m_painter->fillRect(d->m_renderCell, blockBrush); 0574 break; 0575 0576 case Stitch::TLSmallHalf: 0577 d->m_painter->fillRect(d->m_renderTLCell, blockBrush); 0578 break; 0579 0580 case Stitch::TRSmallHalf: 0581 d->m_painter->fillRect(d->m_renderTRCell, blockBrush); 0582 break; 0583 0584 case Stitch::BLSmallHalf: 0585 d->m_painter->fillRect(d->m_renderBLCell, blockBrush); 0586 break; 0587 0588 case Stitch::BRSmallHalf: 0589 d->m_painter->fillRect(d->m_renderBRCell, blockBrush); 0590 break; 0591 0592 case Stitch::TLSmallFull: 0593 d->m_painter->fillRect(d->m_renderTLCell, blockBrush); 0594 break; 0595 0596 case Stitch::TRSmallFull: 0597 d->m_painter->fillRect(d->m_renderTRCell, blockBrush); 0598 break; 0599 0600 case Stitch::BLSmallFull: 0601 d->m_painter->fillRect(d->m_renderBLCell, blockBrush); 0602 break; 0603 0604 case Stitch::BRSmallFull: 0605 d->m_painter->fillRect(d->m_renderBRCell, blockBrush); 0606 break; 0607 0608 case Stitch::FrenchKnot: 0609 break; 0610 } 0611 0612 if (Configuration::renderer_RenderStitchHints()) { 0613 renderStitchHints(stitch); 0614 } 0615 } 0616 } 0617 0618 void Renderer::renderStitchesAsColorBlocksSymbols(StitchQueue *stitchQueue) 0619 { 0620 QBrush blockBrush(Qt::SolidPattern); 0621 0622 int i = stitchQueue->count(); 0623 0624 while (i) { 0625 Stitch *stitch = stitchQueue->at(--i); 0626 DocumentFloss *documentFloss = d->m_pattern->palette().flosses().value(stitch->colorIndex); 0627 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0628 0629 QPen symbolPen = symbol.pen(); 0630 QBrush symbolBrush = symbol.brush(); 0631 0632 if ((d->m_highlight == -1) || (stitch->colorIndex == d->m_highlight)) { 0633 QColor flossColor = documentFloss->flossColor(); 0634 QColor symbolColor = (qGray(flossColor.rgb()) < 128) ? Qt::white : Qt::black; 0635 symbolPen.setColor(symbolColor); 0636 symbolBrush.setColor(symbolColor); 0637 blockBrush.setColor(flossColor); 0638 } else { 0639 symbolPen.setColor(Qt::darkGray); 0640 symbolBrush.setColor(Qt::darkGray); 0641 blockBrush.setColor(Qt::lightGray); 0642 } 0643 0644 d->m_painter->setPen(Qt::NoPen); 0645 d->m_painter->setBrush(blockBrush); 0646 0647 switch (stitch->type) { 0648 case Stitch::Delete: 0649 break; 0650 0651 case Stitch::TLQtr: 0652 d->m_painter->drawPolygon(d->m_renderTLQ); 0653 break; 0654 0655 case Stitch::TRQtr: 0656 d->m_painter->drawPolygon(d->m_renderTRQ); 0657 break; 0658 0659 case Stitch::BLQtr: 0660 d->m_painter->drawPolygon(d->m_renderBLQ); 0661 break; 0662 0663 case Stitch::BTHalf: 0664 d->m_painter->drawPolygon(d->m_renderBLTRH); 0665 break; 0666 0667 case Stitch::TL3Qtr: 0668 d->m_painter->drawPolygon(d->m_renderTL3Q); 0669 break; 0670 0671 case Stitch::BRQtr: 0672 d->m_painter->drawPolygon(d->m_renderBRQ); 0673 break; 0674 0675 case Stitch::TBHalf: 0676 d->m_painter->drawPolygon(d->m_renderTLBRH); 0677 break; 0678 0679 case Stitch::TR3Qtr: 0680 d->m_painter->drawPolygon(d->m_renderTR3Q); 0681 break; 0682 0683 case Stitch::BL3Qtr: 0684 d->m_painter->drawPolygon(d->m_renderBL3Q); 0685 break; 0686 0687 case Stitch::BR3Qtr: 0688 d->m_painter->drawPolygon(d->m_renderBR3Q); 0689 break; 0690 0691 case Stitch::Full: 0692 d->m_painter->fillRect(d->m_renderCell, blockBrush); 0693 break; 0694 0695 case Stitch::TLSmallHalf: 0696 d->m_painter->fillRect(d->m_renderTLCell, blockBrush); 0697 break; 0698 0699 case Stitch::TRSmallHalf: 0700 d->m_painter->fillRect(d->m_renderTRCell, blockBrush); 0701 break; 0702 0703 case Stitch::BLSmallHalf: 0704 d->m_painter->fillRect(d->m_renderBLCell, blockBrush); 0705 break; 0706 0707 case Stitch::BRSmallHalf: 0708 d->m_painter->fillRect(d->m_renderBRCell, blockBrush); 0709 break; 0710 0711 case Stitch::TLSmallFull: 0712 d->m_painter->fillRect(d->m_renderTLCell, blockBrush); 0713 break; 0714 0715 case Stitch::TRSmallFull: 0716 d->m_painter->fillRect(d->m_renderTRCell, blockBrush); 0717 break; 0718 0719 case Stitch::BLSmallFull: 0720 d->m_painter->fillRect(d->m_renderBLCell, blockBrush); 0721 break; 0722 0723 case Stitch::BRSmallFull: 0724 d->m_painter->fillRect(d->m_renderBRCell, blockBrush); 0725 break; 0726 0727 case Stitch::FrenchKnot: 0728 break; 0729 } 0730 0731 d->m_painter->setPen(symbolPen); 0732 d->m_painter->setBrush(symbolBrush); 0733 0734 d->m_painter->drawPath(symbol.path(stitch->type)); 0735 0736 if (Configuration::renderer_RenderStitchHints()) { 0737 renderStitchHints(stitch); 0738 } 0739 } 0740 } 0741 0742 void Renderer::renderStitchHints(Stitch *stitch) 0743 { 0744 d->m_painter->setPen(QPen(Qt::lightGray, 0)); 0745 0746 switch (stitch->type) { 0747 case Stitch::Delete: 0748 break; 0749 0750 case Stitch::TLQtr: 0751 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0752 break; 0753 0754 case Stitch::TRQtr: 0755 d->m_painter->drawLine(d->m_center, d->m_topRight); 0756 break; 0757 0758 case Stitch::BLQtr: 0759 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0760 break; 0761 0762 case Stitch::BTHalf: 0763 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0764 break; 0765 0766 case Stitch::TL3Qtr: 0767 d->m_painter->drawLine(d->m_topRight, d->m_bottomLeft); 0768 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0769 break; 0770 0771 case Stitch::BRQtr: 0772 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0773 break; 0774 0775 case Stitch::TBHalf: 0776 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0777 break; 0778 0779 case Stitch::TR3Qtr: 0780 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0781 d->m_painter->drawLine(d->m_topRight, d->m_center); 0782 break; 0783 0784 case Stitch::BL3Qtr: 0785 d->m_painter->drawLine(d->m_topLeft, d->m_bottomRight); 0786 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0787 break; 0788 0789 case Stitch::BR3Qtr: 0790 d->m_painter->drawLine(d->m_bottomLeft, d->m_topRight); 0791 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0792 break; 0793 0794 case Stitch::Full: 0795 break; 0796 0797 case Stitch::TLSmallHalf: 0798 d->m_painter->drawLine(d->m_centerLeft, d->m_centerTop); 0799 break; 0800 0801 case Stitch::TRSmallHalf: 0802 d->m_painter->drawLine(d->m_centerTop, d->m_centerRight); 0803 break; 0804 0805 case Stitch::BLSmallHalf: 0806 d->m_painter->drawLine(d->m_centerLeft, d->m_centerBottom); 0807 break; 0808 0809 case Stitch::BRSmallHalf: 0810 d->m_painter->drawLine(d->m_centerBottom, d->m_centerRight); 0811 break; 0812 0813 case Stitch::TLSmallFull: 0814 d->m_painter->drawLine(d->m_topLeft, d->m_center); 0815 d->m_painter->drawLine(d->m_centerTop, d->m_centerLeft); 0816 break; 0817 0818 case Stitch::TRSmallFull: 0819 d->m_painter->drawLine(d->m_centerTop, d->m_centerRight); 0820 d->m_painter->drawLine(d->m_center, d->m_topRight); 0821 break; 0822 0823 case Stitch::BLSmallFull: 0824 d->m_painter->drawLine(d->m_centerLeft, d->m_centerBottom); 0825 d->m_painter->drawLine(d->m_bottomLeft, d->m_center); 0826 break; 0827 0828 case Stitch::BRSmallFull: 0829 d->m_painter->drawLine(d->m_center, d->m_bottomRight); 0830 d->m_painter->drawLine(d->m_centerRight, d->m_centerBottom); 0831 break; 0832 0833 case Stitch::FrenchKnot: 0834 break; 0835 } 0836 } 0837 0838 void Renderer::renderBackstitchesAsColorLines(Backstitch *backstitch) 0839 { 0840 QPointF start(QPointF(backstitch->start) / 2); 0841 QPointF end(QPointF(backstitch->end) / 2); 0842 0843 DocumentFloss *documentFloss = d->m_pattern->palette().floss(backstitch->colorIndex); 0844 0845 QPen pen; 0846 0847 if ((d->m_highlight == -1) || (backstitch->colorIndex == d->m_highlight)) { 0848 pen.setColor(documentFloss->flossColor()); 0849 pen.setWidthF(double(documentFloss->backstitchStrands()) / 5); 0850 pen.setCapStyle(Qt::RoundCap); 0851 } else { 0852 pen.setColor(Qt::lightGray); 0853 pen.setWidth(0); 0854 } 0855 0856 d->m_painter->setPen(pen); 0857 d->m_painter->drawLine(start, end); 0858 } 0859 0860 void Renderer::renderBackstitchesAsBlackWhiteSymbols(Backstitch *backstitch) 0861 { 0862 QPointF start(QPointF(backstitch->start) / 2); 0863 QPointF end(QPointF(backstitch->end) / 2); 0864 0865 DocumentFloss *documentFloss = d->m_pattern->palette().floss(backstitch->colorIndex); 0866 0867 QPen pen; 0868 pen.setStyle(documentFloss->backstitchSymbol()); 0869 0870 if ((d->m_highlight == -1) || (backstitch->colorIndex == d->m_highlight)) { 0871 pen.setColor(Qt::black); 0872 pen.setWidthF(double(documentFloss->backstitchStrands()) / 5); 0873 pen.setCapStyle(Qt::RoundCap); 0874 } else { 0875 pen.setColor(Qt::lightGray); 0876 pen.setWidth(0); 0877 } 0878 0879 d->m_painter->setPen(pen); 0880 d->m_painter->drawLine(start, end); 0881 } 0882 0883 void Renderer::renderKnotsAsColorBlocks(Knot *knot) 0884 { 0885 DocumentFloss *documentFloss = d->m_pattern->palette().floss(knot->colorIndex); 0886 0887 QBrush brush(Qt::SolidPattern); 0888 0889 if ((d->m_highlight == -1) || (knot->colorIndex == d->m_highlight)) { 0890 brush.setColor(documentFloss->flossColor()); 0891 } else { 0892 brush.setColor(Qt::lightGray); 0893 } 0894 0895 d->m_painter->setPen(QPen(Qt::NoPen)); 0896 d->m_painter->setBrush(brush); 0897 0898 QRectF rect(0, 0, 0.75, 0.75); 0899 rect.moveCenter(QPointF(knot->position) / 2); 0900 0901 d->m_painter->drawEllipse(rect); 0902 } 0903 0904 void Renderer::renderKnotsAsColorBlocksSymbols(Knot *knot) 0905 { 0906 DocumentFloss *documentFloss = d->m_pattern->palette().floss(knot->colorIndex); 0907 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0908 0909 QPen symbolPen = symbol.pen(); 0910 QBrush symbolBrush = symbol.brush(); 0911 0912 QBrush blockBrush(Qt::SolidPattern); 0913 0914 if ((d->m_highlight == -1) || (knot->colorIndex == d->m_highlight)) { 0915 QColor flossColor = documentFloss->flossColor(); 0916 QColor symbolColor = (qGray(flossColor.rgb()) < 128) ? Qt::white : Qt::black; 0917 symbolPen.setColor(symbolColor); 0918 symbolBrush.setColor(symbolColor); 0919 blockBrush.setColor(flossColor); 0920 } else { 0921 symbolPen.setColor(Qt::darkGray); 0922 symbolBrush.setColor(Qt::darkGray); 0923 blockBrush.setColor(Qt::lightGray); 0924 } 0925 0926 d->m_painter->setPen(QPen(Qt::NoPen)); 0927 d->m_painter->setBrush(blockBrush); 0928 0929 QRectF rect(0, 0, 0.75, 0.75); 0930 rect.moveCenter(QPointF(knot->position) / 2); 0931 0932 d->m_painter->drawEllipse(rect); 0933 d->m_painter->setPen(symbolPen); 0934 d->m_painter->setBrush(symbolBrush); 0935 d->m_painter->drawPath(symbol.path(Stitch::FrenchKnot).translated(QPointF(knot->position) / 2 - QPointF(0.5, 0.5))); 0936 } 0937 0938 void Renderer::renderKnotsAsColorSymbols(Knot *knot) 0939 { 0940 DocumentFloss *documentFloss = d->m_pattern->palette().floss(knot->colorIndex); 0941 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0942 0943 QPen outlinePen(Qt::lightGray, 0); 0944 0945 QPen symbolPen = symbol.pen(); 0946 QBrush symbolBrush = symbol.brush(); 0947 0948 if ((d->m_highlight == -1) || (knot->colorIndex == d->m_highlight)) { 0949 QColor flossColor = documentFloss->flossColor(); 0950 symbolPen.setColor(flossColor); 0951 symbolBrush.setColor(flossColor); 0952 outlinePen.setColor(flossColor); 0953 } else { 0954 symbolPen.setColor(Qt::lightGray); 0955 symbolBrush.setColor(Qt::lightGray); 0956 } 0957 0958 d->m_painter->setPen(outlinePen); 0959 d->m_painter->setBrush(Qt::NoBrush); 0960 0961 QRectF rect(0, 0, 0.75, 0.75); 0962 rect.moveCenter(QPointF(knot->position) / 2); 0963 0964 d->m_painter->drawEllipse(rect); 0965 0966 d->m_painter->setPen(symbolPen); 0967 d->m_painter->setBrush(symbolBrush); 0968 d->m_painter->drawPath(symbol.path(Stitch::FrenchKnot).translated(QPointF(knot->position) / 2 - QPointF(0.5, 0.5))); 0969 } 0970 0971 void Renderer::renderKnotsAsBlackWhiteSymbols(Knot *knot) 0972 { 0973 DocumentFloss *documentFloss = d->m_pattern->palette().floss(knot->colorIndex); 0974 Symbol symbol = d->m_symbolLibrary->symbol(documentFloss->stitchSymbol()); 0975 0976 QPen outlinePen(Qt::lightGray, 0); 0977 0978 QPen symbolPen = symbol.pen(); 0979 QBrush symbolBrush = symbol.brush(); 0980 0981 if ((d->m_highlight == -1) || (knot->colorIndex == d->m_highlight)) { 0982 symbolPen.setColor(Qt::black); 0983 symbolBrush.setColor(Qt::black); 0984 outlinePen.setColor(Qt::black); 0985 } else { 0986 symbolPen.setColor(Qt::lightGray); 0987 symbolBrush.setColor(Qt::lightGray); 0988 } 0989 0990 d->m_painter->setPen(outlinePen); 0991 d->m_painter->setBrush(Qt::NoBrush); 0992 0993 QRectF rect(0, 0, 0.75, 0.75); 0994 rect.moveCenter(QPointF(knot->position) / 2); 0995 0996 d->m_painter->drawEllipse(rect); 0997 0998 d->m_painter->setPen(symbolPen); 0999 d->m_painter->setBrush(symbolBrush); 1000 d->m_painter->drawPath(symbol.path(Stitch::FrenchKnot).translated(QPointF(knot->position) / 2 - QPointF(0.5, 0.5))); 1001 } 1002 1003 Renderer &Renderer::operator=(const Renderer &other) 1004 { 1005 d = other.d; 1006 return *this; 1007 }