From ae380e4eb4bca6fcc5c1ed219db5764df2e96fde Mon Sep 17 00:00:00 2001 From: Craig Watson Date: Sat, 26 Nov 2016 14:20:19 -0500 Subject: [PATCH] Adjust text item size upon loading to account for platform-to-platform variability The same font, in the same point size, can be displayed differently depending on platform (this is a Qt limitation). This can lead to text items being the wrong size when importing a document created on a different computer. As a workaround, when saving a text item to SVG, the size of 1pt in pixels is calculated and saved. Upon loading, this value is calculated again and, if it is different from the saved value, the text item is scaled accordingly. Thus, any document created from this version onward will have correctly-scaled text boxes. If an old document (not containing a pixel-per-point attribute for text items) is loaded, the scene is marked as modified to make sure that all text items are then saved with the pixels-per-point value (even if the document is not edited). This allows old documents to be "fixed" by simply opening them once from a new version of OpenBoard. save text item font size in pixels, and scale it on load fixed loading of text item pixel height Save and load pixels-per-point rather than text pixel height Upon loading a text item from SVG, make sure that it will be saved with a pixel-per-point value --- src/adaptors/UBSvgSubsetAdaptor.cpp | 37 ++++++++++++++++++++++++++--- src/adaptors/UBSvgSubsetAdaptor.h | 2 ++ src/domain/UBGraphicsTextItem.cpp | 33 +++++++++++++++++++++++++ src/domain/UBGraphicsTextItem.h | 2 ++ 4 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/adaptors/UBSvgSubsetAdaptor.cpp b/src/adaptors/UBSvgSubsetAdaptor.cpp index 722569fc..9d6203c1 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.cpp +++ b/src/adaptors/UBSvgSubsetAdaptor.cpp @@ -355,6 +355,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx mScene = 0; UBGraphicsWidgetItem *currentWidget = 0; bool pageDpiSpecified = true; + saveSceneAfterLoading = false; mFileVersion = 40100; // default to 4.1.0 @@ -371,6 +372,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx if (!mScene) { mScene = new UBGraphicsScene(mProxy, false); + mScene->setModified(false); } // introduced in UB 4.2 @@ -914,10 +916,11 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx mScene->addItem(iterator.value()); } - if (mScene) - mScene->setModified(false); + if (mScene) { + mScene->setModified(saveSceneAfterLoading); + mScene->enableUndoRedoStack(); + } - mScene->enableUndoRedoStack(); qDebug() << "loadScene() : created scene and read file"; qDebug() << "spent milliseconds: " << time.elapsed(); return mScene; @@ -2496,6 +2499,7 @@ void UBSvgSubsetAdaptor::UBSvgSubsetWriter::textItemToSvg(UBGraphicsTextItem* it mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "width", QString("%1").arg(item->textWidth())); mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "height", QString("%1").arg(item->textHeight())); + mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "pixels-per-point", QString("%1").arg(item->pixelsPerPoint())); QColor colorDarkBg = item->colorOnDarkBackground(); QColor colorLightBg = item->colorOnLightBackground(); @@ -2522,6 +2526,8 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg() qreal width = mXmlReader.attributes().value("width").toString().toFloat(); qreal height = mXmlReader.attributes().value("height").toString().toFloat(); + qreal originalPixelsPerPoint = mXmlReader.attributes().value(mNamespaceUri, "pixels-per-point").toString().toDouble(); + UBGraphicsTextItem* textItem = new UBGraphicsTextItem(); graphicsItemFromSvg(textItem); @@ -2564,6 +2570,31 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg() if (mXmlReader.name() == "itemTextContent") { text = mXmlReader.readElementText(); textItem->setHtml(text); + + // Fonts sizes are not displayed the same across platforms: e.g a text item with the same + // font size (in Pts) is displayed smaller on Linux than Windows. This messes up layouts + // when importing documents created on another computer, so if a font is being displayed + // at a different size (relative to the rest of the document) than it was when created, + // we adjust its size. + if (originalPixelsPerPoint != 0) { + qreal pixelsPerPoint = textItem->pixelsPerPoint(); + + qDebug() << "Pixels per point: original/current" << originalPixelsPerPoint + << "/" << pixelsPerPoint; + qreal ratio = originalPixelsPerPoint/pixelsPerPoint; + + if (ratio != 1) { + qDebug() << "Scaling text by " << ratio; + UBGraphicsTextItemDelegate* textDelegate = dynamic_cast(textItem->Delegate()); + if (textDelegate) + textDelegate->scaleTextSize(ratio); + } + } + else + // mark scene as modified so the text item will be saved with a pixelsPerPoint value + saveSceneAfterLoading = true; + + textItem->resize(width, height); if (textItem->toPlainText().isEmpty()) { delete textItem; diff --git a/src/adaptors/UBSvgSubsetAdaptor.h b/src/adaptors/UBSvgSubsetAdaptor.h index 48e3b1d7..5124e013 100644 --- a/src/adaptors/UBSvgSubsetAdaptor.h +++ b/src/adaptors/UBSvgSubsetAdaptor.h @@ -168,6 +168,8 @@ class UBSvgSubsetAdaptor qreal mGroupZIndex; bool mGroupHasInfo; + bool saveSceneAfterLoading; + QString mNamespaceUri; UBGraphicsScene *mScene; diff --git a/src/domain/UBGraphicsTextItem.cpp b/src/domain/UBGraphicsTextItem.cpp index e48cbb5b..5ef3b738 100644 --- a/src/domain/UBGraphicsTextItem.cpp +++ b/src/domain/UBGraphicsTextItem.cpp @@ -328,6 +328,39 @@ qreal UBGraphicsTextItem::textHeight() const return mTextHeight; } +/** + * @brief Get the ratio between font size in pixels and points. + * @return The ratio of pixel size to point size of the first character, or 0 if the text item is empty. + * + * Qt may display fonts differently on different platforms -- on the same display, + * the same point size may be displayed at different pixel sizes. This function returns the + * ratio of pixel size to point size, based on the first character in the text item. + */ +qreal UBGraphicsTextItem::pixelsPerPoint() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return 0; + + cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); + cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); + + QFont f = cursor.charFormat().font(); + qDebug() << "ppp. Font: " << f; + QFontInfo fi(cursor.charFormat().font()); + + qreal pixelSize = fi.pixelSize(); + qreal pointSize = fi.pointSizeF(); + + //qDebug() << "Pixel size: " << pixelSize; + //qDebug() << "Point size: " << pointSize; + + if (pointSize == 0) + return 0; + + return pixelSize/pointSize; +} + void UBGraphicsTextItem::contentsChanged() { diff --git a/src/domain/UBGraphicsTextItem.h b/src/domain/UBGraphicsTextItem.h index bb001a26..bb031f71 100644 --- a/src/domain/UBGraphicsTextItem.h +++ b/src/domain/UBGraphicsTextItem.h @@ -65,6 +65,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes void setTextWidth(qreal width); void setTextHeight(qreal height); qreal textHeight() const; + qreal pixelsPerPoint() const; void contentsChanged(); @@ -101,6 +102,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes QString mTypeTextHereLabel; + signals: void textUndoCommandAdded(UBGraphicsTextItem *textItem);