Added new headers to cff import sources.

Improved rectangles and ellipses import (each element havs separate bounding box).
Added textArea and text tags import
preferencesAboutTextFull
ivan.ilyin 13 years ago
parent 104c60d1ab
commit 6140939038
  1. 486
      src/adaptors/UBCFFSubsetAdaptor.cpp
  2. 27
      src/adaptors/UBCFFSubsetAdaptor.h
  3. 25
      src/adaptors/UBImportCFF.cpp
  4. 15
      src/adaptors/UBImportCFF.h

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QRegExp> #include <QRegExp>
#include <QSvgGenerator> #include <QSvgGenerator>
#include <QSvgRenderer> #include <QSvgRenderer>
#include "UBCFFSubsetAdaptor.h"
#include "core/UBPersistenceManager.h" #include "core/UBPersistenceManager.h"
#include "document/UBDocumentProxy.h" #include "document/UBDocumentProxy.h"
#include "domain/UBItem.h" #include "domain/UBItem.h"
#include "domain/UBGraphicsPolygonItem.h" #include "domain/UBGraphicsPolygonItem.h"
#include "domain/UBGraphicsStroke.h" #include "domain/UBGraphicsStroke.h"
#include "domain/UBGraphicsTextItem.h"
#include "domain/UBGraphicsSvgItem.h"
#include "UBCFFSubsetAdaptor.h"
#include "UBMetadataDcSubsetAdaptor.h" #include "UBMetadataDcSubsetAdaptor.h"
#include "UBThumbnailAdaptor.h" #include "UBThumbnailAdaptor.h"
#include "UBSvgSubsetAdaptor.h" #include "UBSvgSubsetAdaptor.h"
@ -28,7 +44,10 @@ static char* tPageset = "pageset";
static char* tPolygon = "polygon"; static char* tPolygon = "polygon";
static char* tRect = "rect"; static char* tRect = "rect";
static char* tSvg = "svg"; static char* tSvg = "svg";
static char* tText = "text";
static char* tTextarea = "textarea"; static char* tTextarea = "textarea";
static char* tTspan = "tspan";
static char* tBreak = "tbreak";
//attribute names definition //attribute names definition
static char* aFill = "fill"; static char* aFill = "fill";
@ -45,6 +64,13 @@ static char* aRx = "rx";
static char* aRy = "ry"; static char* aRy = "ry";
static char* aTransform = "transform"; static char* aTransform = "transform";
static char* aViewbox = "viewbox"; 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() UBCFFSubsetAdaptor::UBCFFSubsetAdaptor()
{ {
@ -82,10 +108,8 @@ bool UBCFFSubsetAdaptor::ConvertCFFFileToUbz(QString &cffSourceFile, UBDocumentP
UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QByteArray &content): UBCFFSubsetAdaptor::UBCFFSubsetReader::UBCFFSubsetReader(UBDocumentProxy *proxy, QByteArray &content):
mReader(content), mProxy(proxy), currentState(NONE) mReader(content), mProxy(proxy), currentState(NONE)
{ {
//TODO parse
} }
bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse() bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parse()
{ {
UBMetadataDcSubsetAdaptor::persist(mProxy); UBMetadataDcSubsetAdaptor::persist(mProxy);
@ -187,6 +211,12 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseCurrentElementStart()
return false; return false;
} }
else else
if ( elName == tText)
{
if (!parseText())
return false;
}
else
if ( elName == tTextarea) if ( elName == tTextarea)
{ {
if (!parseTextArea()) if (!parseTextArea())
@ -300,6 +330,37 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseSvg()
return true; 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() bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect()
{ {
if (currentState != SVG && currentState != PAGE) if (currentState != SVG && currentState != PAGE)
@ -312,11 +373,6 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseRect()
if (currentState == SVG && mCurrentScene == NULL) if (currentState == SVG && mCurrentScene == NULL)
createNewScene(); 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 //rect lef top corner coordinates
qreal x1 = mReader.attributes().value(aX).toString().toDouble(); qreal x1 = mReader.attributes().value(aX).toString().toDouble();
qreal y1 = mReader.attributes().value(aY).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(); qreal height = mReader.attributes().value(aHeight).toString().toDouble();
//init svg generator with temp file //init svg generator with temp file
QSvgGenerator *generator = createSvgGenerator(); QSvgGenerator *generator = createSvgGenerator(width + 10, height + 10);
//init painter to paint to svg //init painter to paint to svg
QPainter painter; QPainter painter;
painter.begin(generator); painter.begin(generator);
//check if rect is rotated //fill rect
if (mReader.attributes().hasAttribute(aTransform)) if (mReader.attributes().hasAttribute(aFill))
{ {
QTransform transform = transformFromString(mReader.attributes().value(aTransform).toString()); QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString());
painter.setTransform(transform); painter.setBrush(QBrush(fillColor));
//change left top coordinates to correspond to transformation painter.fillRect(5, 5, width, height, fillColor);
x1 -= transform.dx();
y1 -= transform.dy();
} }
painter.setBrush(QBrush(fillColor)); bool hasStrokeColor = mReader.attributes().hasAttribute(aStroke);
painter.fillRect(x1, y1, width, height, fillColor); 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());
QPen pen(strokeColor);
pen.setWidth(strokeWidth);
painter.setPen(pen); painter.setPen(pen);
painter.drawRect(x1, y1, width, height); painter.drawRect(5, 5, width, height);
}
painter.end(); painter.end();
//add resulting svg file to scene //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; delete generator;
return true; return true;
@ -370,7 +433,10 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseEllipse()
if (currentState == SVG && mCurrentScene == NULL) if (currentState == SVG && mCurrentScene == NULL)
createNewScene(); 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 //fill and stroke color
QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString()); QColor fillColor = colorFromString(mReader.attributes().value(aFill).toString());
@ -380,44 +446,33 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseEllipse()
//ellipse center coordinates //ellipse center coordinates
qreal cx = mReader.attributes().value(aCx).toString().toDouble(); qreal cx = mReader.attributes().value(aCx).toString().toDouble();
qreal cy = mReader.attributes().value(aCy).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 //init painter to paint to svg
QPainter painter; QPainter painter;
painter.begin(generator); 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); QPen pen(strokeColor);
pen.setWidth(strokeWidth); pen.setWidth(strokeWidth);
painter.setPen(pen); painter.setPen(pen);
painter.setBrush(QBrush(fillColor)); painter.setBrush(QBrush(fillColor));
painter.drawEllipse(cx, cy, rx * 2, ry * 2); painter.drawEllipse(5, 5, rx * 2, ry * 2);
painter.end(); painter.end();
//add resulting svg file to scene //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; delete generator;
return true; return true;
} }
bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea() bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea()
{ {
@ -431,6 +486,258 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseTextArea()
if (currentState == SVG && mCurrentScene == NULL) if (currentState == SVG && mCurrentScene == NULL)
createNewScene(); 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<QRectF> textRects;
QList<QFont> textFonts;
QList<QString> textLines;
QList<int> textAligns;
QList<QColor> 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<QFont> fontStack;
QStack<QColor> colorStack;
QStack<int> 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<QRectF> textRectsIter(textRects);
QListIterator<QFont> textFontsIter(textFonts);
QListIterator<QString> textLinesIter(textLines);
QListIterator<int> textAlignsIter(textAligns);
QListIterator<QColor> 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; return true;
} }
@ -459,6 +766,8 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parsePage()
createNewScene(); createNewScene();
qWarning() << "Added page number" << mProxy->pageCount();
return true; return true;
} }
@ -487,6 +796,7 @@ bool UBCFFSubsetAdaptor::UBCFFSubsetReader::parseIwbElementRef()
bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene() bool UBCFFSubsetAdaptor::UBCFFSubsetReader::createNewScene()
{ {
mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount()); mCurrentScene = UBPersistenceManager::persistenceManager()->createDocumentSceneAt(mProxy, mProxy->pageCount());
mCurrentSceneRect = mCurrentScene->normalizedSceneRect();
return true; return true;
} }
@ -530,10 +840,21 @@ QColor UBCFFSubsetAdaptor::UBCFFSubsetReader::colorFromString(const QString& clr
return QColor(clrString); 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) QTransform UBCFFSubsetAdaptor::UBCFFSubsetReader::transformFromString(const QString trString)
{ {
//check pattern for strings like 'rotate(10)' //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.exactMatch(trString))
{ {
if (regexp.capturedTexts().count() == 2 && regexp.capturedTexts().at(0).length() == trString.length()) 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)' //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.exactMatch(trString))
{ {
if (regexp.capturedTexts().count() == 4 && regexp.capturedTexts().at(0).length() == trString.length()) 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()) if (capturesCount == 5 && regexp.capturedTexts().at(0).length() == viewBox.length())
{ {
mViewBox = QRectF(0, 0, regexp.capturedTexts().at(3).toDouble(), regexp.capturedTexts().at(4).toDouble()); 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; return true;
} }
} }
mViewBox = QRectF(0, 0, 1000, 1000); mViewBox = QRectF(0, 0, 1000, 1000);
mViewBoxCenter = QPointF(500, 500);
return false; return false;
} }
QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator() QSvgGenerator* UBCFFSubsetAdaptor::UBCFFSubsetReader::createSvgGenerator(qreal width, qreal height)
{ {
QSvgGenerator* generator = new QSvgGenerator(); 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->setFileName(mTempFilePath);
generator->setSize(mSize); generator->setSize(QSize(width, height));
generator->setViewBox(mViewBox); generator->setViewBox(QRectF(0, 0, width, height));
return generator; 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());
}

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef UBCFFSUBSETADAPTOR_H #ifndef UBCFFSUBSETADAPTOR_H
#define UBCFFSUBSETADAPTOR_H #define UBCFFSUBSETADAPTOR_H
@ -8,6 +23,8 @@
class UBDocumentProxy; class UBDocumentProxy;
class UBGraphicsScene; class UBGraphicsScene;
class QSvgGenerator; class QSvgGenerator;
class UBGraphicsSvgItem;
class QTransform;
class UBCFFSubsetAdaptor class UBCFFSubsetAdaptor
{ {
@ -42,8 +59,10 @@ private:
private: private:
QString mTempFilePath; QString mTempFilePath;
UBGraphicsScene *mCurrentScene; UBGraphicsScene *mCurrentScene;
QRectF mCurrentSceneRect;
QString mIndent; QString mIndent;
QRectF mViewBox; QRectF mViewBox;
QPointF mViewBoxCenter;
QSize mSize; QSize mSize;
//methods to store current xml parse state //methods to store current xml parse state
@ -63,6 +82,7 @@ private:
bool parseRect(); bool parseRect();
bool parseEllipse(); bool parseEllipse();
bool parseTextArea(); bool parseTextArea();
bool parseText();
bool parsePolygon(); bool parsePolygon();
bool parsePage(); bool parsePage();
bool parsePageSet(); bool parsePageSet();
@ -75,11 +95,16 @@ private:
int currentState; int currentState;
//helper methods //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); QColor colorFromString(const QString& clrString);
QTransform transformFromString(const QString trString); QTransform transformFromString(const QString trString);
bool getViewBoxDimenstions(const QString& viewBox); bool getViewBoxDimenstions(const QString& viewBox);
QSvgGenerator* createSvgGenerator(); QSvgGenerator* createSvgGenerator(qreal width, qreal height);
bool getTempFileName(); bool getTempFileName();
void parseTextAttributes(qreal &fontSize, QColor &fontColor,
QString &fontFamily, QString &fontStretch, bool &italic,
int &fontWeight, int &textAlign, QTransform &fontTransform);
}; };
}; };

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <QDir> #include <QDir>
#include "UBImportCFF.h"
#include "document/UBDocumentProxy.h"
#include "core/UBApplication.h" #include "core/UBApplication.h"
#include "core/UBPersistenceManager.h" #include "core/UBPersistenceManager.h"
#include "core/UBDocumentManager.h" #include "core/UBDocumentManager.h"
#include "core/memcheck.h" #include "core/memcheck.h"
#include "core/UBPersistenceManager.h" #include "core/UBPersistenceManager.h"
#include "document/UBDocumentProxy.h"
#include "frameworks/UBFileSystemUtils.h"
#include "domain/UBGraphicsPDFItem.h" #include "domain/UBGraphicsPDFItem.h"
#include "frameworks/UBFileSystemUtils.h"
#include "pdf/PDFRenderer.h" #include "pdf/PDFRenderer.h"
#include "UBCFFSubsetAdaptor.h" #include "UBCFFSubsetAdaptor.h"
#include "UBImportCFF.h"
#include "quazip.h" #include "quazip.h"
#include "quazipfile.h" #include "quazipfile.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 <http://www.gnu.org/licenses/>.
*/
#ifndef UBIMPORTCFF_H #ifndef UBIMPORTCFF_H
#define UBIMPORTCFF_H #define UBIMPORTCFF_H

Loading…
Cancel
Save