From 6140939038f38b67a8ba8498d7721a4e2e9adb19 Mon Sep 17 00:00:00 2001 From: "ivan.ilyin" Date: Wed, 17 Aug 2011 16:10:09 +0300 Subject: [PATCH] Added new headers to cff import sources. Improved rectangles and ellipses import (each element havs separate bounding box). Added textArea and text tags import --- src/adaptors/UBCFFSubsetAdaptor.cpp | 490 +++++++++++++++++++++++++--- src/adaptors/UBCFFSubsetAdaptor.h | 27 +- src/adaptors/UBImportCFF.cpp | 25 +- src/adaptors/UBImportCFF.h | 15 + 4 files changed, 497 insertions(+), 60 deletions(-) diff --git a/src/adaptors/UBCFFSubsetAdaptor.cpp b/src/adaptors/UBCFFSubsetAdaptor.cpp index 7a62d39c..8405e898 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.cpp +++ b/src/adaptors/UBCFFSubsetAdaptor.cpp @@ -1,16 +1,32 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include #include #include -#include "UBCFFSubsetAdaptor.h" - #include "core/UBPersistenceManager.h" #include "document/UBDocumentProxy.h" #include "domain/UBItem.h" #include "domain/UBGraphicsPolygonItem.h" #include "domain/UBGraphicsStroke.h" +#include "domain/UBGraphicsTextItem.h" +#include "domain/UBGraphicsSvgItem.h" +#include "UBCFFSubsetAdaptor.h" #include "UBMetadataDcSubsetAdaptor.h" #include "UBThumbnailAdaptor.h" #include "UBSvgSubsetAdaptor.h" @@ -28,7 +44,10 @@ static char* tPageset = "pageset"; static char* tPolygon = "polygon"; static char* tRect = "rect"; static char* tSvg = "svg"; +static char* tText = "text"; static char* tTextarea = "textarea"; +static char* tTspan = "tspan"; +static char* tBreak = "tbreak"; //attribute names definition static char* aFill = "fill"; @@ -45,6 +64,13 @@ static char* aRx = "rx"; static char* aRy = "ry"; static char* aTransform = "transform"; static char* aViewbox = "viewbox"; +static char* aFontSize = "font-size"; +static char* aFontfamily = "font-family"; +static char* aFontstretch = "font-stretch"; +static char* aFontstyle = "font-style"; +static char* aFontweight = "font-weight"; +static char* aTextalign = "text-align"; + UBCFFSubsetAdaptor::UBCFFSubsetAdaptor() { @@ -82,10 +108,8 @@ bool UBCFFSubsetAdaptor::ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentP UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QByteArray &content): mReader(content), mProxy(proxy), currentState(NONE) { - //TODO parse } - bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse() { UBMetadataDcSubsetAdaptor::persist(mProxy); @@ -187,6 +211,12 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseCurrentElementStart() return false; } else + if ( elName == tText) + { + if (!parseText()) + return false; + } + else if ( elName == tTextarea) { if (!parseTextArea()) @@ -300,6 +330,37 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg() return true; } +void UBCFFSubsetAdaptor::UBCFFSubsetReader::repositionSvgItem(UBGraphicsSvgItem *item, qreal width, qreal height, qreal x, qreal y, bool useTransform, QTransform &transform) +{ + QTransform curTrans = item->transform(); + qWarning() << QString().sprintf("Item current transform = %f 0 0 %f %f %f, position %f, %f, size %f, %f", curTrans.m11(), curTrans.m22(), curTrans.dx(), curTrans.dy(), item->x(), item->y()); + //check if rect is rotated + //rotate svg item itself + QRectF itemBounds = item->boundingRect(); + //first, svg is mapped to svg item bound + //second, svg item is mapped to scene + //so, get svg to svg item scale and multiple by scene scale + qreal hScale = itemBounds.width() / width * curTrans.m11(); + qreal vScale = itemBounds.height() / height * curTrans.m22(); + + if (useTransform) + { + QPointF oldVector((x - transform.dx()), (y - transform.dy())); + QTransform rTransform(transform.m11(), transform.m12(), transform.m21(), transform.m22(), 0, 0); + QPointF newVector = rTransform.map(oldVector); + rTransform.scale(curTrans.m11(), curTrans.m22()); + item->setTransform(QTransform(rTransform.m11(), rTransform.m12(), rTransform.m21(), rTransform.m22(), 0, 0)); + item->setPos((x - mViewBoxCenter.x() + (newVector - oldVector).x()) * hScale, (y - mViewBoxCenter.y() + (newVector - oldVector).y()) * vScale ); + } + else + { + item->setPos((x - mViewBoxCenter.x()) * hScale, (y - mViewBoxCenter.y()) * vScale); + } + + QTransform newTrans = item->transform(); + qWarning() << QString("Item new transform = %3 0 0 %4 %1 %2, position %5, %6").arg(newTrans.dx()).arg(newTrans.dy()).arg(newTrans.m11()).arg(newTrans.m22()).arg(item->x()).arg(item->y()); +} + bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect() { if (currentState != SVG && currentState != PAGE) @@ -312,11 +373,6 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect() if (currentState == SVG && mCurrentScene == NULL) createNewScene(); - //fill and stroke color - QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString()); - QColor strokeColor = colorFromString(mReader.attributes().value(aStroke).toString()); - int strokeWidth = mReader.attributes().value(aStrokewidth).toString().toInt(); - //rect lef top corner coordinates qreal x1 = mReader.attributes().value(aX).toString().toDouble(); qreal y1 = mReader.attributes().value(aY).toString().toDouble(); @@ -325,34 +381,41 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect() qreal height = mReader.attributes().value(aHeight).toString().toDouble(); //init svg generator with temp file - QSvgGenerator *generator = createSvgGenerator(); + QSvgGenerator *generator = createSvgGenerator(width + 10, height + 10); //init painter to paint to svg QPainter painter; painter.begin(generator); - //check if rect is rotated - if (mReader.attributes().hasAttribute(aTransform)) + //fill rect + if (mReader.attributes().hasAttribute(aFill)) { - QTransform transform = transformFromString(mReader.attributes().value(aTransform).toString()); - painter.setTransform(transform); - //change left top coordinates to correspond to transformation - x1 -= transform.dx(); - y1 -= transform.dy(); + QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString()); + painter.setBrush(QBrush(fillColor)); + painter.fillRect(5, 5, width, height, fillColor); } - painter.setBrush(QBrush(fillColor)); - painter.fillRect(x1, y1, width, height, fillColor); - - QPen pen(strokeColor); - pen.setWidth(strokeWidth); - painter.setPen(pen); - painter.drawRect(x1, y1, width, height); + bool hasStrokeColor = mReader.attributes().hasAttribute(aStroke); + bool hasStrokeWidth = mReader.attributes().hasAttribute(aStrokewidth); + if (hasStrokeColor || hasStrokeWidth) + { + QPen pen; + if (hasStrokeColor) + pen.setColor(colorFromString(mReader.attributes().value(aStroke).toString())); + if (hasStrokeWidth) + pen.setWidth(mReader.attributes().value(aStrokewidth).toString().toInt()); + + painter.setPen(pen); + painter.drawRect(5, 5, width, height); + } painter.end(); //add resulting svg file to scene - mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + QTransform transform; + bool hastransform = getCurElementTransorm(transform); + repositionSvgItem(svgItem, width + 10, height + 10, x1 - 5, y1 - 5, hastransform, transform); delete generator; return true; @@ -370,7 +433,10 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseEllipse() if (currentState == SVG && mCurrentScene == NULL) createNewScene(); - QSvgGenerator *generator = createSvgGenerator(); + //ellipse horisontal and vertical radius + qreal rx = mReader.attributes().value(aRx).toString().toDouble(); + qreal ry = mReader.attributes().value(aRy).toString().toDouble(); + QSvgGenerator *generator = createSvgGenerator(rx * 2 + 10, ry * 2 + 10); //fill and stroke color QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString()); @@ -380,44 +446,33 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseEllipse() //ellipse center coordinates qreal cx = mReader.attributes().value(aCx).toString().toDouble(); qreal cy = mReader.attributes().value(aCy).toString().toDouble(); - //ellipse horisontal and vertical radius - qreal rx = mReader.attributes().value(aRx).toString().toDouble(); - qreal ry = mReader.attributes().value(aRy).toString().toDouble(); - - //we should change cx and cy by rx and ry because qpainter - //draws ellipse by its rect coordinates - cx -= rx; - cy -= ry; //init painter to paint to svg QPainter painter; painter.begin(generator); - //check if ellipse is rotated - if (mReader.attributes().hasAttribute(aTransform)) - { - QTransform transform = transformFromString(mReader.attributes().value(aTransform).toString()); - painter.setTransform(transform); - //change cx and cy to correspond to transformation - cx -= transform.dx(); - cy -= transform.dy(); - } - QPen pen(strokeColor); pen.setWidth(strokeWidth); painter.setPen(pen); painter.setBrush(QBrush(fillColor)); - painter.drawEllipse(cx, cy, rx * 2, ry * 2); + painter.drawEllipse(5, 5, rx * 2, ry * 2); painter.end(); + //add resulting svg file to scene - mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + QTransform transform; + bool hasTransform = getCurElementTransorm(transform); + + repositionSvgItem(svgItem, rx * 2 + 10, ry * 2 + 10, cx - rx - 5, cy - ry -5, hasTransform, transform); + delete generator; return true; -} + } bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea() { @@ -431,6 +486,258 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea() if (currentState == SVG && mCurrentScene == NULL) createNewScene(); + //TODO textarea node + qreal x = mReader.attributes().value(aX).toString().toDouble(); + qreal y = mReader.attributes().value(aY).toString().toDouble(); + qreal width = mReader.attributes().value(aWidth).toString().toDouble(); + qreal height = mReader.attributes().value(aHeight).toString().toDouble(); + + qWarning() << QString().sprintf("Text coordinates : %f,%f. Text size %f,%f", x, y, width, height); + + qreal fontSize = 12.0; + QColor fontColor; + QString fontFamily = "Arial"; + QString fontStretch = "normal"; + bool italic = false; + int fontWeight = QFont::Normal; + int textAlign = Qt::AlignLeft; + QTransform fontTransform; + parseTextAttributes(fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + + QSvgGenerator *generator = createSvgGenerator(width, height); + qreal hScale = 1;//mCurrentSceneRect.width() / mViewBox.width(); + qreal vScale = 1;//mCurrentSceneRect.height() / mViewBox.height(); + QPainter painter; + painter.begin(generator); + painter.setFont(QFont(fontFamily, fontSize, fontWeight, italic)); + + qreal curY = 0.0; + qreal curX = 0.0; + qreal linespacing = QFontMetricsF(painter.font()).leading(); + + //remember if text area has transform + QString transformString; + QTransform transform; + bool hasTransform = getCurElementTransorm(transform); + + QRectF lastDrawnTextBoundingRect; + //parse text area tags + while(true) + { + mReader.readNext(); + QStringRef elementName = mReader.name(); + if (mReader.isEndDocument()) + break; + if (mReader.isEndElement() && elementName == tBreak) + { + //when tbreak appers, move down by the drawn rect height + //TODO: line spacing is not calculated yet, additional code is required + curY += lastDrawnTextBoundingRect.height() + linespacing; + curX = 0.0; + lastDrawnTextBoundingRect = QRectF(0,0,0,0); + continue; + } + if (mReader.isEndElement() && elementName == tTextarea) + break; + if (mReader.isStartElement() && elementName == tTspan) + { + parseTextAttributes(fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + painter.setFont(QFont(fontFamily, fontSize, fontWeight, italic)); + painter.setPen(fontColor); + linespacing = QFontMetricsF(painter.font()).leading(); + continue; + } + if (mReader.isCharacters() || mReader.isCDATA()) + { + QString text = mReader.text().toString().trimmed(); + + //skip empty text + if (text.length() == 0) + continue; + + //get bounding rect to obtain desired text height + lastDrawnTextBoundingRect = painter.boundingRect(QRectF(curX, curY, width, height - curY), textAlign|Qt::TextWordWrap, text); + QString log = QString().sprintf(" at rect %f, %f, %f, %f. Bounding rect is %f, %f, %f, %f", 0.0, curY, width, height - curY, lastDrawnTextBoundingRect.x(), lastDrawnTextBoundingRect.y(), lastDrawnTextBoundingRect.width(), lastDrawnTextBoundingRect.height()); + qWarning() << "Text " << text << log; + painter.drawText(curX, curY, width, lastDrawnTextBoundingRect.height(), textAlign|Qt::TextWordWrap, text); + curX += lastDrawnTextBoundingRect.x() + lastDrawnTextBoundingRect.width(); + + continue; + } + } + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + + repositionSvgItem(svgItem, width, height, x, y, hasTransform, transform); + delete generator; + + return true; +} + +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseText() +{ + if (currentState != SVG && currentState != PAGE) + { + qWarning() << "iwb content parse error, unexpected textarea tag at line" << mReader.lineNumber(); + return false; + } + + //create new scene if it's not created yet (for one page document case) + if (currentState == SVG && mCurrentScene == NULL) + createNewScene(); + + qreal x = mReader.attributes().value(aX).toString().toDouble(); + qreal y = mReader.attributes().value(aY).toString().toDouble(); + + qreal width = 0; + qreal height = 0; + + QList textRects; + QList textFonts; + QList textLines; + QList textAligns; + QList textColors; + + qWarning() << QString().sprintf("Text coordinates : %f,%f. Text size %f,%f", x, y, width, height); + + qreal fontSize = 12.0; + QFont textFont; + QColor fontColor; + QString fontFamily = "Arial"; + QString fontStretch = "normal"; + + bool italic = false; + int fontWeight = QFont::Normal; + int textAlign = Qt::AlignLeft; + QTransform fontTransform; + parseTextAttributes(fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + textFont = QFont(fontFamily, fontSize, fontWeight, italic); + + QFontMetricsF metrics = QFontMetricsF(textFont); + qreal curHeight = metrics.height(); + + qreal curY = 0.0; + qreal curX = 0.0; + + qreal linespacing = QFontMetrics(textFont).leading(); + + //remember if text area has transform + QTransform transform; + bool hasTransform = getCurElementTransorm(transform); + + QRectF lastDrawnTextBoundingRect; + + QStack fontStack; + QStack colorStack; + QStack alignStack; + + // first extimate desired text area size + // to do that, parse text area tags + while(true) + { + mReader.readNext(); + QStringRef elementName = mReader.name(); + if (mReader.isEndDocument()) + break; + if (mReader.isEndElement()) + { + if (elementName == tBreak) + { + //when tbreak appers, move down by the drawn rect height + //TODO: line spacing is not calculated yet, probably additional code is required + curY += lastDrawnTextBoundingRect.height() + linespacing; + curX = 0.0; + height += lastDrawnTextBoundingRect.height(); + lastDrawnTextBoundingRect = QRectF(0,0,0,0); + continue; + } + if (elementName == tTspan) + { + textFont = fontStack.pop(); + fontColor = colorStack.pop(); + textAlign = alignStack.pop(); + continue; + } + } + if (mReader.isEndElement() && elementName == tText) + break; + if (mReader.isStartElement() && elementName == tTspan) + { + fontStack.push(textFont); + colorStack.push(fontColor); + alignStack.push(textAlign); + + parseTextAttributes(fontSize, fontColor, fontFamily, fontStretch, italic, fontWeight, textAlign, fontTransform); + textFont = QFont(fontFamily, fontSize, fontWeight, italic); + metrics = QFontMetricsF(textFont); + curHeight = metrics.height(); + linespacing = QFontMetricsF(textFont).leading(); + continue; + } + if (mReader.isCharacters() || mReader.isCDATA()) + { + QString text = mReader.text().toString(); + + //skip empty text + if (text.trimmed().length() == 0) + continue; + //get bounding rect to obtain desired text height + qreal lWidth = metrics.width(text); + lastDrawnTextBoundingRect = metrics.boundingRect(QRectF(), textAlign, text); + /*lastDrawnTextBoundingRect = QRectF(curX, curY, metrics.width(text), curHeight);*/ + QString log = QString().sprintf(" at rect %f, %f, %f, %f. Bounding rect is %f, %f, %f, %f", 0.0, curY, width, height - curY, lastDrawnTextBoundingRect.x(), lastDrawnTextBoundingRect.y(), lastDrawnTextBoundingRect.width(), lastDrawnTextBoundingRect.height()); + qWarning() << "Text " << text << log; + textFonts.append(textFont); + textRects.append(QRectF(curX, curY, lastDrawnTextBoundingRect.width(), lastDrawnTextBoundingRect.height())); + textLines.append(text); + textAligns.append(textAlign); + textColors.append(fontColor); + curX += lastDrawnTextBoundingRect.width(); + if (width < curX) + width = curX; + if (height == 0) + height = curHeight; + + continue; + } + } + + QSvgGenerator *generator = createSvgGenerator(width, height); + QPainter painter; + painter.begin(generator); + + if (textRects.count() != 0) + { + QListIterator textRectsIter(textRects); + QListIterator textFontsIter(textFonts); + QListIterator textLinesIter(textLines); + QListIterator textAlignsIter(textAligns); + QListIterator textColorsIter(textColors); + + while (textRectsIter.hasNext()) + { + QRectF rt = textRectsIter.next(); + QFont font = textFontsIter.next(); + QString line = textLinesIter.next(); + int align = textAlignsIter.next(); + QColor color = textColorsIter.next(); + painter.setFont(font); + painter.setPen(color); + painter.drawText(rt.x(), rt.y(), rt.width(), rt.height(), align, line); + } + } + + painter.end(); + + //add resulting svg file to scene + UBGraphicsSvgItem *svgItem = mCurrentScene->addSvg(QUrl::fromLocalFile(generator->fileName())); + repositionSvgItem(svgItem, width, height, x, y, hasTransform, transform); + + delete generator; + return true; } @@ -459,6 +766,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parsePage() createNewScene(); + qWarning() << "Added page number" << mProxy->pageCount(); + return true; } @@ -487,6 +796,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElementRef() bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene() { mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount()); + mCurrentSceneRect = mCurrentScene->normalizedSceneRect(); return true; } @@ -530,10 +840,21 @@ QColor UBCFFSubsetAdaptor::UBCFFSubsetReader::colorFromString(const QString& clr return QColor(clrString); } +bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getCurElementTransorm(QTransform &transform) +{ + if (mReader.attributes().hasAttribute(aTransform)) + { + transform = transformFromString(mReader.attributes().value(aTransform).toString()); + return true; + } + else + return false; +} + QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QString trString) { //check pattern for strings like 'rotate(10)' - QRegExp regexp("rotate\\(([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)\\)"); + QRegExp regexp("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); if (regexp.exactMatch(trString)) { if (regexp.capturedTexts().count() == 2 && regexp.capturedTexts().at(0).length() == trString.length()) @@ -544,7 +865,7 @@ QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QStr } //check pattern for strings like 'rotate(10,20,20)' or 'rotate(10.1,10.2,34.2)' - regexp.setPattern("rotate\\(([-+]{0,1}[0-9]*\\.{0,1}[0-9]*),([-+]{0,1}[0-9]*\\.{0,1}[0-9]*),([-+]{0,1}[0-9]*\\.{0,1}[0-9]*)\\)"); + regexp.setPattern("rotate\\( *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *, *([-+]{0,1}[0-9]*\\.{0,1}[0-9]*) *\\)"); if (regexp.exactMatch(trString)) { if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == trString.length()) @@ -569,20 +890,26 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getViewBoxDimenstions(const QString& if (capturesCount == 5 && regexp.capturedTexts().at(0).length() == viewBox.length()) { mViewBox = QRectF(0, 0, regexp.capturedTexts().at(3).toDouble(), regexp.capturedTexts().at(4).toDouble()); + mViewBoxCenter.setX(mViewBox.width() / 2); + mViewBoxCenter.setY(mViewBox.height() / 2); return true; } } mViewBox = QRectF(0, 0, 1000, 1000); + mViewBoxCenter = QPointF(500, 500); return false; } -QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator() +QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator(qreal width, qreal height) { QSvgGenerator* generator = new QSvgGenerator(); + qWarning() << QString("Making generator with file %1, size (%2, %3) and viewbox (%4 %5 %6 %7)").arg(mTempFilePath) + .arg(width).arg(height).arg(0.0).arg(0.0).arg(width).arg(width); + generator->setResolution(QApplication::desktop()->physicalDpiY()); generator->setFileName(mTempFilePath); - generator->setSize(mSize); - generator->setViewBox(mViewBox); + generator->setSize(QSize(width, height)); + generator->setViewBox(QRectF(0, 0, width, height)); return generator; } @@ -608,3 +935,62 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::getTempFileName() } } + +void UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextAttributes(qreal &fontSize, QColor &fontColor, + QString &fontFamily, QString &fontStretch, bool &italic, + int &fontWeight, int &textAlign, QTransform &fontTransform) +{ + if (mReader.attributes().hasAttribute(aFontSize)) + { + //consider inch has 72 liens + //since svg font size is given in pixels, divide it by pixels per line + fontSize = mReader.attributes().value(aFontSize).toString().toDouble() * 72 / QApplication::desktop()->physicalDpiY(); + } + + if (mReader.attributes().hasAttribute(aFill)) + fontColor = colorFromString(mReader.attributes().value(aFill).toString()); + + if (mReader.attributes().hasAttribute(aFontfamily)) + fontFamily = mReader.attributes().value(aFontfamily).toString(); + + if (mReader.attributes().hasAttribute(aFontstretch)) + fontStretch = mReader.attributes().value(aFontstretch).toString(); + + if (mReader.attributes().hasAttribute(aFontstyle)) + { + QStringRef fontStyle = mReader.attributes().value(aFontstyle); + italic = fontStyle == "italic"; + } + + if (mReader.attributes().hasAttribute(aFontweight)) + { + QStringRef weight = mReader.attributes().value(aFontweight); + if (weight == "normal") + fontWeight = QFont::Normal; + else if (weight == "light") + fontWeight = QFont::Light; + else if (weight == "demibold") + fontWeight = QFont::DemiBold; + else if (weight == "bold") + fontWeight = QFont::Bold; + if (weight == "black") + fontWeight = QFont::Black; + } + + if (mReader.attributes().hasAttribute(aTextalign)) + { + QString align = mReader.attributes().value(aTextalign).toString(); + if (align == "middle" || align == "center") + textAlign = Qt::AlignHCenter; + else + if (align == "start") + textAlign = Qt::AlignLeft; + else + if (align == "end") + textAlign = Qt::AlignRight; + } + + if (mReader.attributes().hasAttribute(aTransform)) + fontTransform = transformFromString(mReader.attributes().value(aTransform).toString()); +} + diff --git a/src/adaptors/UBCFFSubsetAdaptor.h b/src/adaptors/UBCFFSubsetAdaptor.h index ac3d6142..1b692a1f 100644 --- a/src/adaptors/UBCFFSubsetAdaptor.h +++ b/src/adaptors/UBCFFSubsetAdaptor.h @@ -1,3 +1,18 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef UBCFFSUBSETADAPTOR_H #define UBCFFSUBSETADAPTOR_H @@ -8,6 +23,8 @@ class UBDocumentProxy; class UBGraphicsScene; class QSvgGenerator; +class UBGraphicsSvgItem; +class QTransform; class UBCFFSubsetAdaptor { @@ -42,8 +59,10 @@ private: private: QString mTempFilePath; UBGraphicsScene *mCurrentScene; + QRectF mCurrentSceneRect; QString mIndent; QRectF mViewBox; + QPointF mViewBoxCenter; QSize mSize; //methods to store current xml parse state @@ -63,6 +82,7 @@ private: bool parseRect(); bool parseEllipse(); bool parseTextArea(); + bool parseText(); bool parsePolygon(); bool parsePage(); bool parsePageSet(); @@ -75,11 +95,16 @@ private: int currentState; //helper methods + bool getCurElementTransorm(QTransform &transform); + void repositionSvgItem(UBGraphicsSvgItem *item, qreal width, qreal height, qreal x, qreal y, bool useTransform, QTransform &transform); QColor colorFromString(const QString& clrString); QTransform transformFromString(const QString trString); bool getViewBoxDimenstions(const QString& viewBox); - QSvgGenerator* createSvgGenerator(); + QSvgGenerator* createSvgGenerator(qreal width, qreal height); bool getTempFileName(); + void parseTextAttributes(qreal &fontSize, QColor &fontColor, + QString &fontFamily, QString &fontStretch, bool &italic, + int &fontWeight, int &textAlign, QTransform &fontTransform); }; }; diff --git a/src/adaptors/UBImportCFF.cpp b/src/adaptors/UBImportCFF.cpp index c79f316b..8329eb61 100644 --- a/src/adaptors/UBImportCFF.cpp +++ b/src/adaptors/UBImportCFF.cpp @@ -1,21 +1,32 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #include -#include "UBImportCFF.h" -#include "document/UBDocumentProxy.h" #include "core/UBApplication.h" #include "core/UBPersistenceManager.h" #include "core/UBDocumentManager.h" #include "core/memcheck.h" #include "core/UBPersistenceManager.h" - -#include "frameworks/UBFileSystemUtils.h" - +#include "document/UBDocumentProxy.h" #include "domain/UBGraphicsPDFItem.h" - +#include "frameworks/UBFileSystemUtils.h" #include "pdf/PDFRenderer.h" - #include "UBCFFSubsetAdaptor.h" +#include "UBImportCFF.h" #include "quazip.h" #include "quazipfile.h" diff --git a/src/adaptors/UBImportCFF.h b/src/adaptors/UBImportCFF.h index a7de5414..3b5b0577 100644 --- a/src/adaptors/UBImportCFF.h +++ b/src/adaptors/UBImportCFF.h @@ -1,3 +1,18 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + #ifndef UBIMPORTCFF_H #define UBIMPORTCFF_H