QString patternPrinter::flossToCode(const typedFloss& f, bool useCodeAbbreviations) const { const int code = f.code(); QString codeString; if (code != -1) { // valid floss if (code >= 0) { codeString = ::itoqs(code); } else { // the code is a string in this case if (code == WHITE_CODE) { codeString = "White"; } else if (code == ECRU_CODE) { codeString = "Ecru"; } else if (code == SNOW_WHITE_CODE) { codeString = "Snow White"; } else { qWarning() << "String code error."; codeString = "N/A"; } } if (useCodeAbbreviations) { codeString = f.type().prefix() + codeString; } return codeString; } else { // use the rgb code instead of the dmc code return ::ctos(f.color()); } }
bool typedFloss::operator<(const typedFloss& f) const { if (f.type() != type()) { return type().value() < f.type().value(); } else if (type() != flossVariable) { return code() < f.code(); } else { // both are variable return color().intensity() < f.color().intensity(); } }
void patternPrinter::drawColorList(int startHeight) { painter_.save(); int yused = startHeight; // have the list font match the symbol size, within reason // TODO: limit so that overflow isn't possible int symbolDim = qMax(pdfSymbolDim_, sHeight("B")); symbolDim = qMin(symbolDim, 35); ::setFontHeight(&painter_, symbolDim); const QFont listFont = painter_.font(); const QFontMetrics listFontMetric(listFont); const int fontHeight = listFontMetric.height(); //// list color count and box dimensions QRect textBoundingRect; painter_.drawText(QRect(0, yused + fontHeight, printerWidth_, 4 * fontHeight), Qt::TextWordWrap, QObject::tr("The pattern uses %1 colors and is %2 " "squares wide by %3 squares high.") .arg(::itoqs(colors_.size())) .arg(::itoqs(xBoxes_)) .arg(::itoqs(yBoxes_)), &textBoundingRect); yused += textBoundingRect.height() + fontHeight; const bool useCodeAbbreviations = printListDescription(&yused, fontHeight); // save this height so it can be restored for a second column const int yusedSaved = yused; //// now draw the color list QFont boldFont = listFont; boldFont.setBold(true); painter_.setFont(boldFont); const QFontMetrics boldFontMetric(boldFont); //// tab stops const int padding = 10; const int swatchTab = symbolDim + 5; const int countTab = 2 * swatchTab + padding; const int codeTab = countTab + listFontMetric.width("99999999") + padding; const int nameTab = codeTab + listFontMetric.width("255 255 255") + padding; const int endTab = nameTab + boldFontMetric.width("~8888:Ultra V DK Turquoise"); yused += fontHeight; drawListHeader(0, yused, countTab, codeTab, nameTab); painter_.drawLine(0, yused + 3, endTab, yused + 3); yused += 5; painter_.setFont(listFont); int xtab = 0; bool partial = true; // the first page list may be a partial page QVector<typedFloss> flossVector = ::rgbToFloss(colors_); std::sort(flossVector.begin(), flossVector.end(), flossIntensity()); // build a color count map QHash<QRgb, int> countsHash; ::colorCounts(squareImage_, squareDim_, &countsHash); QPixmap thisSymbol; QPainter symbolPainter; QPixmap thisPixmap(symbolDim, symbolDim); QString thisCodeString; for (int i = 0, size = flossVector.size(); i < size; ++i) { const typedFloss thisFloss = flossVector[i]; if (yused + fontHeight > printerHeight_) { // out of room in this column // if we're currently in a second column or there isn't room for a // second column, then start a new page if (xtab > 0 || endTab + 50 + endTab > printerWidth_) { xtab = 0; printer_.newPage(); partial = false; yused = 0; painter_.setFont(boldFont); drawListHeader(xtab, fontHeight, countTab, codeTab, nameTab); painter_.setFont(listFont); yused += fontHeight; painter_.drawLine(xtab, yused + 3, endTab, yused + 3); yused += 5; } else { // start a second column xtab = endTab + 50; painter_.setFont(boldFont); if (partial) { // second column on first page of listing yused = yusedSaved; drawListHeader(xtab, fontHeight + yused, countTab, codeTab, nameTab); yused += fontHeight; } else { yused = 0; drawListHeader(xtab, fontHeight, countTab, codeTab, nameTab); yused += fontHeight; } painter_.setFont(listFont); painter_.drawLine(xtab, yused + 3, endTab + xtab, yused + 3); yused += 5; } } //// symbol thisSymbol = imageContainer_->symbolNoBorder(thisFloss.color(), symbolDim); symbolPainter.begin(&thisSymbol); symbolPainter.drawRect(0, 0, thisSymbol.width() - 1, thisSymbol.height() - 1); symbolPainter.end(); painter_.drawPixmap(xtab, yused + 5, thisSymbol); //// color swatch ("sample") thisPixmap.fill(thisFloss.color().qc()); painter_.drawPixmap(swatchTab + xtab + 2, yused + 5, thisPixmap); painter_.drawRect(swatchTab + xtab + 2, yused + 5, symbolDim, symbolDim); //// color count painter_.drawText(countTab + xtab, yused + symbolDim, ::itoqs(countsHash[thisFloss.color().qrgb()])); //// floss code (or rgb code) painter_.drawText(codeTab + xtab, yused + symbolDim, flossToCode(thisFloss, useCodeAbbreviations)); //// color name painter_.drawText(nameTab + xtab, yused + symbolDim, thisFloss.name()); yused += symbolDim + 5; } printer_.newPage(); painter_.restore(); }
bool operator()(const typedFloss& f1, const typedFloss& f2) const { return ::definiteIntensityCompare(f1.color(), f2.color()); }