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
preferencesAboutTextFull
Craig Watson 8 years ago
parent 4cff84737d
commit ae380e4eb4
  1. 37
      src/adaptors/UBSvgSubsetAdaptor.cpp
  2. 2
      src/adaptors/UBSvgSubsetAdaptor.h
  3. 33
      src/domain/UBGraphicsTextItem.cpp
  4. 2
      src/domain/UBGraphicsTextItem.h

@ -355,6 +355,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
mScene = 0; mScene = 0;
UBGraphicsWidgetItem *currentWidget = 0; UBGraphicsWidgetItem *currentWidget = 0;
bool pageDpiSpecified = true; bool pageDpiSpecified = true;
saveSceneAfterLoading = false;
mFileVersion = 40100; // default to 4.1.0 mFileVersion = 40100; // default to 4.1.0
@ -371,6 +372,7 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
if (!mScene) if (!mScene)
{ {
mScene = new UBGraphicsScene(mProxy, false); mScene = new UBGraphicsScene(mProxy, false);
mScene->setModified(false);
} }
// introduced in UB 4.2 // introduced in UB 4.2
@ -914,10 +916,11 @@ UBGraphicsScene* UBSvgSubsetAdaptor::UBSvgSubsetReader::loadScene(UBDocumentProx
mScene->addItem(iterator.value()); mScene->addItem(iterator.value());
} }
if (mScene) if (mScene) {
mScene->setModified(false); mScene->setModified(saveSceneAfterLoading);
mScene->enableUndoRedoStack(); mScene->enableUndoRedoStack();
}
qDebug() << "loadScene() : created scene and read file"; qDebug() << "loadScene() : created scene and read file";
qDebug() << "spent milliseconds: " << time.elapsed(); qDebug() << "spent milliseconds: " << time.elapsed();
return mScene; 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, "width", QString("%1").arg(item->textWidth()));
mXmlWriter.writeAttribute(UBSettings::uniboardDocumentNamespaceUri, "height", QString("%1").arg(item->textHeight())); 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 colorDarkBg = item->colorOnDarkBackground();
QColor colorLightBg = item->colorOnLightBackground(); QColor colorLightBg = item->colorOnLightBackground();
@ -2522,6 +2526,8 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg()
qreal width = mXmlReader.attributes().value("width").toString().toFloat(); qreal width = mXmlReader.attributes().value("width").toString().toFloat();
qreal height = mXmlReader.attributes().value("height").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(); UBGraphicsTextItem* textItem = new UBGraphicsTextItem();
graphicsItemFromSvg(textItem); graphicsItemFromSvg(textItem);
@ -2564,6 +2570,31 @@ UBGraphicsTextItem* UBSvgSubsetAdaptor::UBSvgSubsetReader::textItemFromSvg()
if (mXmlReader.name() == "itemTextContent") { if (mXmlReader.name() == "itemTextContent") {
text = mXmlReader.readElementText(); text = mXmlReader.readElementText();
textItem->setHtml(text); 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<UBGraphicsTextItemDelegate*>(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); textItem->resize(width, height);
if (textItem->toPlainText().isEmpty()) { if (textItem->toPlainText().isEmpty()) {
delete textItem; delete textItem;

@ -168,6 +168,8 @@ class UBSvgSubsetAdaptor
qreal mGroupZIndex; qreal mGroupZIndex;
bool mGroupHasInfo; bool mGroupHasInfo;
bool saveSceneAfterLoading;
QString mNamespaceUri; QString mNamespaceUri;
UBGraphicsScene *mScene; UBGraphicsScene *mScene;

@ -328,6 +328,39 @@ qreal UBGraphicsTextItem::textHeight() const
return mTextHeight; 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() void UBGraphicsTextItem::contentsChanged()
{ {

@ -65,6 +65,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes
void setTextWidth(qreal width); void setTextWidth(qreal width);
void setTextHeight(qreal height); void setTextHeight(qreal height);
qreal textHeight() const; qreal textHeight() const;
qreal pixelsPerPoint() const;
void contentsChanged(); void contentsChanged();
@ -101,6 +102,7 @@ class UBGraphicsTextItem : public QGraphicsTextItem, public UBItem, public UBRes
QString mTypeTextHereLabel; QString mTypeTextHereLabel;
signals: signals:
void textUndoCommandAdded(UBGraphicsTextItem *textItem); void textUndoCommandAdded(UBGraphicsTextItem *textItem);

Loading…
Cancel
Save