diff --git a/toonz/sources/toonz/exportxsheetpdf.cpp b/toonz/sources/toonz/exportxsheetpdf.cpp index 0c09c23..4b95abb 100644 --- a/toonz/sources/toonz/exportxsheetpdf.cpp +++ b/toonz/sources/toonz/exportxsheetpdf.cpp @@ -377,23 +377,43 @@ QComboBox* createTickMarkCombo(QWidget* parent) { return combo; } -} // namespace -//--------------------------------------------------------- - -void XSheetPDFTemplate::adjustSpacing(QPainter& painter, const int width, - const QString& label, - const double ratio) { - QFont font = painter.font(); - int thresWidth = (int)((double)width * ratio); - int spacing = 300; - while (spacing > 0) { - font.setLetterSpacing(QFont::PercentageSpacing, spacing); - if (QFontMetrics(font).boundingRect(label).width() <= thresWidth) break; - spacing -= 50; +void doDrawText(QPainter& p, const QString& str, const QRect rect) { + QFontMetrics fm(p.font()); + int spaceWidth = fm.boundingRect('A').width(); + // check if spaces can be iserted between letters + int textWidth = fm.boundingRect(str).width() + spaceWidth * (str.count() - 1); + if (rect.width() - spaceWidth * 2 <= textWidth) { + p.drawText(rect, Qt::AlignCenter, str); + return; } - painter.setFont(font); + // check if spaces can be doubled + int textWidth_s2 = + fm.boundingRect(str).width() + spaceWidth * 2 * (str.count() - 1); + if (rect.width() - spaceWidth * 4 > textWidth_s2) textWidth = textWidth_s2; + QRect textRect(rect.center().x() - textWidth / 2, rect.y(), textWidth, + rect.height()); + p.drawText(textRect, + Qt::TextJustificationForced | Qt::AlignJustify | Qt::AlignVCenter, + str); +} + +void setFontFittingRectWidth(QPainter& p, const QString& str, const QRect rect, + double vmargin = 0.5, double hmargin = 1.0) { + QFont font = p.font(); + int pixelSize = rect.height() - mm2px(vmargin); + while (1) { + font.setPixelSize(pixelSize); + if (pixelSize <= mm2px(2) || QFontMetrics(font).boundingRect(str).width() <= + rect.width() - mm2px(hmargin)) + break; + pixelSize -= mm2px(0.1); + } + p.setFont(font); } +} // namespace +//--------------------------------------------------------- + void XSheetPDFTemplate::drawGrid(QPainter& painter, int colAmount, int colWidth, int blockWidth) { // horiontal lines @@ -577,7 +597,6 @@ void XSheetPDFTemplate::drawKeyBlock(QPainter& painter, int framePage, const int bodyId) { QFont font = painter.font(); font.setPixelSize(m_p.bodylabelTextSize_Small); - font.setLetterSpacing(QFont::PercentageSpacing, 200); painter.setFont(font); painter.save(); @@ -600,7 +619,7 @@ void XSheetPDFTemplate::drawKeyBlock(QPainter& painter, int framePage, QString actionLabel = (param(TranslateBodyLabel, 1) == 1) ? QObject::tr("ACTION", "XSheetPDF") : "ACTION"; - painter.drawText(labelRect, Qt::AlignCenter, actionLabel); + doDrawText(painter, actionLabel, labelRect); painter.save(); { @@ -676,7 +695,7 @@ void XSheetPDFTemplate::drawKeyBlock(QPainter& painter, int framePage, painter.restore(); painter.translate(m_p.keyBlockWidth, 0); - painter.setPen(thinPen); + painter.setPen(blockBorderPen); painter.drawLine(0, 0, 0, param(BodyHeight)); } painter.restore(); @@ -749,7 +768,7 @@ void XSheetPDFTemplate::drawDialogBlock(QPainter& painter, const int framePage, painter.save(); { - painter.setPen(thinPen); + painter.setPen(blockBorderPen); painter.translate(param(DialogColWidth), 0); painter.drawLine(0, 0, 0, param(BodyHeight)); } @@ -759,7 +778,6 @@ void XSheetPDFTemplate::drawDialogBlock(QPainter& painter, const int framePage, void XSheetPDFTemplate::drawCellsBlock(QPainter& painter, int bodyId) { QFont font = painter.font(); font.setPixelSize(m_p.bodylabelTextSize_Small); - font.setLetterSpacing(QFont::PercentageSpacing, 200); painter.setFont(font); painter.save(); @@ -783,7 +801,7 @@ void XSheetPDFTemplate::drawCellsBlock(QPainter& painter, int bodyId) { QString cellsLabel = (param(TranslateBodyLabel, 1) == 1) ? QObject::tr("CELL", "XSheetPDF") : "CELL"; - painter.drawText(labelRect, Qt::AlignCenter, cellsLabel); + doDrawText(painter, cellsLabel, labelRect); } painter.save(); @@ -800,7 +818,7 @@ void XSheetPDFTemplate::drawCellsBlock(QPainter& painter, int bodyId) { } painter.restore(); - painter.setPen(thinPen); + painter.setPen(blockBorderPen); painter.translate(m_p.cellsBlockWidth, 0); painter.drawLine(0, 0, 0, param(BodyHeight)); } @@ -810,7 +828,6 @@ void XSheetPDFTemplate::drawCellsBlock(QPainter& painter, int bodyId) { void XSheetPDFTemplate::drawCameraBlock(QPainter& painter) { QFont font = painter.font(); font.setPixelSize(m_p.bodylabelTextSize_Large); - font.setLetterSpacing(QFont::PercentageSpacing, 150); painter.setFont(font); painter.save(); @@ -828,7 +845,7 @@ void XSheetPDFTemplate::drawCameraBlock(QPainter& painter) { font.setPixelSize(m_p.bodylabelTextSize_Small); painter.setFont(font); QRect labelRect(0, 0, m_p.cameraBlockWidth, param(HeaderHeight) / 2); - painter.drawText(labelRect, Qt::AlignCenter, cameraLabel); + doDrawText(painter, cameraLabel, labelRect); } } else { // horizontal lines @@ -840,7 +857,7 @@ void XSheetPDFTemplate::drawCameraBlock(QPainter& painter) { font.setPixelSize(m_p.bodylabelTextSize_Large); painter.setFont(font); QRect labelRect(0, 0, m_p.cameraBlockWidth, param(HeaderHeight)); - painter.drawText(labelRect, Qt::AlignCenter, cameraLabel); + doDrawText(painter, cameraLabel, labelRect); } } } @@ -865,7 +882,7 @@ void XSheetPDFTemplate::drawXsheetBody(QPainter& painter, int framePage, // Body painter.save(); { - painter.setPen(thickPen); + painter.setPen(bodyOutlinePen); painter.drawRect(QRect(0, 0, param(BodyWidth), param(BodyHeight))); drawKeyBlock(painter, framePage, bodyId); @@ -883,26 +900,29 @@ void XSheetPDFTemplate::drawInfoHeader(QPainter& painter) { painter.save(); { painter.translate(param(InfoOriginLeft), param(InfoOriginTop)); - painter.setPen(thinPen); QFont font = painter.font(); font.setPixelSize(param(InfoTitleHeight) - mm2px(2)); - font.setLetterSpacing(QFont::PercentageSpacing, 200); painter.setFont(font); + bool isLeftMost = true; // draw each info for (auto info : m_p.array_Infos) { + painter.setPen((isLeftMost) ? bodyOutlinePen : thinPen); + isLeftMost = false; // vertical line painter.drawLine(0, 0, 0, m_p.infoHeaderHeight); // 3 horizontal lines - painter.drawLine(0, 0, info.width, 0); + painter.setPen(thinPen); painter.drawLine(0, param(InfoTitleHeight), info.width, param(InfoTitleHeight)); + painter.setPen(bodyOutlinePen); + painter.drawLine(0, 0, info.width, 0); painter.drawLine(0, m_p.infoHeaderHeight, info.width, m_p.infoHeaderHeight); + painter.setPen(thinPen); // label QRect labelRect(0, 0, info.width, param(InfoTitleHeight)); - adjustSpacing(painter, labelRect.width(), info.label); - painter.drawText(labelRect, Qt::AlignCenter, info.label); + doDrawText(painter, info.label, labelRect); if (info.decoFunc) { painter.save(); @@ -919,6 +939,7 @@ void XSheetPDFTemplate::drawInfoHeader(QPainter& painter) { painter.translate(info.width, 0); } // vertical line at the rightmost edge + painter.setPen(bodyOutlinePen); painter.drawLine(0, 0, 0, m_p.infoHeaderHeight); } painter.restore(); @@ -1287,11 +1308,14 @@ XSheetPDFTemplate::XSheetPDFTemplate( : m_columns(columns), m_duration(duration), m_useExtraColumns(false) {} void XSheetPDFTemplate::setInfo(const XSheetPDFFormatInfo& info) { - m_info = info; - thinPen = QPen(info.lineColor, mm2px(0.25), Qt::SolidLine, Qt::FlatCap, - Qt::MiterJoin); - thickPen = QPen(info.lineColor, mm2px(0.5), Qt::SolidLine, Qt::FlatCap, - Qt::MiterJoin); + m_info = info; + thinPen = QPen(info.lineColor, param(ThinLineWidth, mm2px(0.25)), + Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); + thickPen = QPen(info.lineColor, param(ThickLineWidth, mm2px(0.5)), + Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); + bodyOutlinePen = QPen(info.lineColor, param(BodyOutlineWidth, mm2px(0.5)), + Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); + blockBorderPen = (param(IsBlockBorderThick, 0) > 0) ? thickPen : thinPen; // check if it should use extra columns if (info.exportArea == Area_Cells && param(ExtraCellsColAmount, 0) > 0) { int colsInScene = m_columns.size(); @@ -1485,48 +1509,38 @@ void XSheetPDFTemplate::drawXsheetContents(QPainter& painter, int framePage, painter.restore(); if (m_dataRects.contains(Data_Second) && m_duration >= 24) { - font.setPixelSize(m_dataRects.value(Data_Second).height() - mm2px(1)); - painter.setFont(font); - painter.drawText(m_dataRects.value(Data_Second), Qt::AlignCenter, - QString::number(m_duration / 24)); + QString str = QString::number(m_duration / 24); + setFontFittingRectWidth(painter, str, m_dataRects.value(Data_Second)); + painter.drawText(m_dataRects.value(Data_Second), Qt::AlignCenter, str); } if (m_dataRects.contains(Data_Frame) && m_duration > 0) { - font.setPixelSize(m_dataRects.value(Data_Frame).height() - mm2px(1)); - painter.setFont(font); - painter.drawText(m_dataRects.value(Data_Frame), Qt::AlignCenter, - QString::number(m_duration % 24)); + QString str = QString::number(m_duration % 24); + setFontFittingRectWidth(painter, str, m_dataRects.value(Data_Frame)); + painter.drawText(m_dataRects.value(Data_Frame), Qt::AlignCenter, str); } if (m_dataRects.contains(Data_TotalPages)) { QString totStr = QString::number(framePageCount()); if (parallelPageCount() > 1) totStr += "x" + QString::number(parallelPageCount()); - font.setPixelSize(m_dataRects.value(Data_TotalPages).height() - mm2px(0.5)); - painter.setFont(font); + + setFontFittingRectWidth(painter, totStr, + m_dataRects.value(Data_TotalPages)); painter.drawText(m_dataRects.value(Data_TotalPages), Qt::AlignCenter, totStr); } if (m_dataRects.contains(Data_CurrentPage)) { QString curStr = QString::number(framePage + 1); if (parallelPageCount() > 1) curStr += QChar('A' + parallelPage); - font.setPixelSize(m_dataRects.value(Data_CurrentPage).height() - - mm2px(0.5)); - painter.setFont(font); + + setFontFittingRectWidth(painter, curStr, + m_dataRects.value(Data_CurrentPage)); painter.drawText(m_dataRects.value(Data_CurrentPage), Qt::AlignLeft | Qt::AlignVCenter, curStr); } if (m_dataRects.contains(Data_SceneName) && !m_info.sceneNameText.isEmpty()) { - int pixelSize = m_dataRects.value(Data_SceneName).height() - mm2px(1); - QRect rect = m_dataRects.value(Data_SceneName); - while (1) { - font.setPixelSize(pixelSize); - if (pixelSize <= mm2px(2) || - QFontMetrics(font).boundingRect(m_info.sceneNameText).width() < - rect.width() - mm2px(1)) - break; - pixelSize -= mm2px(0.2); - } - painter.setFont(font); + QRect rect = m_dataRects.value(Data_SceneName); + setFontFittingRectWidth(painter, m_info.sceneNameText, rect); painter.drawText(rect, Qt::AlignCenter, m_info.sceneNameText); } } diff --git a/toonz/sources/toonz/exportxsheetpdf.h b/toonz/sources/toonz/exportxsheetpdf.h index 0fe5bf0..583d812 100644 --- a/toonz/sources/toonz/exportxsheetpdf.h +++ b/toonz/sources/toonz/exportxsheetpdf.h @@ -49,23 +49,28 @@ const std::string DrawCameraHeaderLabel = "DrawCameraHeaderLabel"; const std::string DrawCellsHeaderLabel = "DrawCellsHeaderLabel"; const std::string TranslateBodyLabel = "TranslateBodyLabel"; const std::string TranslateInfoLabel = "TranslateInfoLabel"; +const std::string IsBlockBorderThick = "IsBlockBorderThick"; + // lengths -const std::string BodyWidth = "BodyWidth"; -const std::string BodyHeight = "BodyHeight"; -const std::string BodyHMargin = "BodyHMargin"; -const std::string BodyTop = "BodyTop"; -const std::string HeaderHeight = "HeaderHeight"; -const std::string KeyColWidth = "KeyColWidth"; -const std::string LastKeyColWidth = "LastKeyColWidth"; -const std::string DialogColWidth = "DialogColWidth"; -const std::string CellsColWidth = "CellsColWidth"; -const std::string CameraColWidth = "CameraColWidth"; -const std::string RowHeight = "RowHeight"; -const std::string OneSecHeight = "1SecHeight"; -const std::string InfoOriginLeft = "InfoOriginLeft"; -const std::string InfoOriginTop = "InfoOriginTop"; -const std::string InfoTitleHeight = "InfoTitleHeight"; -const std::string InfoBodyHeight = "InfoBodyHeight"; +const std::string BodyWidth = "BodyWidth"; +const std::string BodyHeight = "BodyHeight"; +const std::string BodyHMargin = "BodyHMargin"; +const std::string BodyTop = "BodyTop"; +const std::string HeaderHeight = "HeaderHeight"; +const std::string KeyColWidth = "KeyColWidth"; +const std::string LastKeyColWidth = "LastKeyColWidth"; +const std::string DialogColWidth = "DialogColWidth"; +const std::string CellsColWidth = "CellsColWidth"; +const std::string CameraColWidth = "CameraColWidth"; +const std::string RowHeight = "RowHeight"; +const std::string OneSecHeight = "1SecHeight"; +const std::string InfoOriginLeft = "InfoOriginLeft"; +const std::string InfoOriginTop = "InfoOriginTop"; +const std::string InfoTitleHeight = "InfoTitleHeight"; +const std::string InfoBodyHeight = "InfoBodyHeight"; +const std::string ThinLineWidth = "ThinLineWidth"; +const std::string ThickLineWidth = "ThickLineWidth"; +const std::string BodyOutlineWidth = "BodyOutlineWidth"; }; // namespace XSheetPDFTemplateParamIDs // ids for various information area @@ -137,7 +142,7 @@ protected: QMap m_params; - QPen thinPen, thickPen; + QPen thinPen, thickPen, blockBorderPen, bodyOutlinePen; XSheetPDFFormatInfo m_info;