Commit c9c5eb78 authored by Oliver Sander's avatar Oliver Sander Committed by Albert Astals Cid
Browse files

Use std::vector to store dash patterns

Makes the code more readable.
parent b8aaf51d
......@@ -515,8 +515,6 @@ AnnotQuadrilaterals::AnnotQuadrilateral::AnnotQuadrilateral(double x1, double y1
AnnotBorder::AnnotBorder()
{
width = 1;
dashLength = 0;
dash = nullptr;
style = borderSolid;
}
......@@ -524,7 +522,7 @@ bool AnnotBorder::parseDashArray(Object *dashObj)
{
bool correct = true;
const int tempLength = dashObj->arrayGetLength();
double *tempDash = (double *)gmallocn(tempLength, sizeof(double));
std::vector<double> tempDash(tempLength);
// TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
for (int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
......@@ -539,22 +537,14 @@ bool AnnotBorder::parseDashArray(Object *dashObj)
}
if (correct) {
dashLength = tempLength;
dash = tempDash;
dash = std::move(tempDash);
style = borderDashed;
} else {
gfree(tempDash);
}
return correct;
}
AnnotBorder::~AnnotBorder()
{
if (dash) {
gfree(dash);
}
}
AnnotBorder::~AnnotBorder() = default;
//------------------------------------------------------------------------
// AnnotBorderArray
......@@ -618,11 +608,7 @@ std::unique_ptr<AnnotBorder> AnnotBorderArray::copy() const
AnnotBorderArray *res = new AnnotBorderArray();
res->type = type;
res->width = width;
res->dashLength = dashLength;
if (dashLength > 0) {
res->dash = (double *)gmallocn(dashLength, sizeof(double));
memcpy(res->dash, dash, dashLength * sizeof(double));
}
res->dash = dash;
res->style = style;
res->horizontalCorner = horizontalCorner;
res->verticalCorner = verticalCorner;
......@@ -636,11 +622,11 @@ Object AnnotBorderArray::writeToObject(XRef *xref) const
borderArray->add(Object(verticalCorner));
borderArray->add(Object(width));
if (dashLength > 0) {
if (dash.size() > 0) {
Array *a = new Array(xref);
for (int i = 0; i < dashLength; i++) {
a->add(Object(dash[i]));
for (double d : dash) {
a->add(Object(d));
}
borderArray->add(Object(a));
......@@ -686,14 +672,8 @@ AnnotBorderBS::AnnotBorderBS(Dict *dict)
// Border dash style
if (style == borderDashed) {
obj1 = dict->lookup("D");
if (obj1.isArray()) {
parseDashArray(&obj1);
}
if (!dash) {
dashLength = 1;
dash = (double *)gmallocn(dashLength, sizeof(double));
dash[0] = 3;
if (!obj1.isArray() || !parseDashArray(&obj1)) {
dash = { 3 };
}
}
}
......@@ -721,11 +701,7 @@ std::unique_ptr<AnnotBorder> AnnotBorderBS::copy() const
AnnotBorderBS *res = new AnnotBorderBS();
res->type = type;
res->width = width;
res->dashLength = dashLength;
if (dashLength > 0) {
res->dash = (double *)gmallocn(dashLength, sizeof(double));
memcpy(res->dash, dash, dashLength * sizeof(double));
}
res->dash = dash;
res->style = style;
return std::unique_ptr<AnnotBorder>(res);
}
......@@ -735,11 +711,11 @@ Object AnnotBorderBS::writeToObject(XRef *xref) const
Dict *dict = new Dict(xref);
dict->set("W", Object(width));
dict->set("S", Object(objName, getStyleName()));
if (style == borderDashed && dashLength > 0) {
if (style == borderDashed && dash.size() > 0) {
Array *a = new Array(xref);
for (int i = 0; i < dashLength; i++) {
a->add(Object(dash[i]));
for (double d : dash) {
a->add(Object(d));
}
dict->set("D", Object(a));
}
......@@ -1736,16 +1712,11 @@ void AnnotAppearanceBuilder::setTextFont(const Object &fontName, double fontSize
void AnnotAppearanceBuilder::setLineStyleForBorder(const AnnotBorder *border)
{
int i, dashLength;
double *dash;
switch (border->getStyle()) {
case AnnotBorder::borderDashed:
appearBuf->append("[");
dashLength = border->getDashLength();
dash = border->getDash();
for (i = 0; i < dashLength; ++i) {
appearBuf->appendf(" {0:.2f}", dash[i]);
for (double dash : border->getDash()) {
appearBuf->appendf(" {0:.2f}", dash);
}
appearBuf->append(" ] 0 d\n");
break;
......@@ -5026,8 +4997,6 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect)
{
int dashLength;
double *dash;
AnnotColor adjustedColor;
const double w = border->getWidth();
......@@ -5049,10 +5018,8 @@ void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const Annot
switch (border->getStyle()) {
case AnnotBorder::borderDashed:
appearBuf->append("[");
dashLength = border->getDashLength();
dash = border->getDash();
for (int i = 0; i < dashLength; ++i) {
appearBuf->appendf(" {0:.2f}", dash[i]);
for (double dash : border->getDash()) {
appearBuf->appendf(" {0:.2f}", dash);
}
appearBuf->append("] 0 d\n");
// fallthrough
......@@ -5081,10 +5048,8 @@ void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const Annot
switch (border->getStyle()) {
case AnnotBorder::borderDashed:
appearBuf->append("[");
dashLength = border->getDashLength();
dash = border->getDash();
for (int i = 0; i < dashLength; ++i) {
appearBuf->appendf(" {0:.2f}", dash[i]);
for (double dash : border->getDash()) {
appearBuf->appendf(" {0:.2f}", dash);
}
appearBuf->append("] 0 d\n");
// fallthrough
......
......@@ -281,8 +281,7 @@ public:
virtual AnnotBorderType getType() const = 0;
virtual double getWidth() const { return width; }
virtual int getDashLength() const { return dashLength; }
virtual double *getDash() const { return dash; }
virtual const std::vector<double> &getDash() const { return dash; }
virtual AnnotBorderStyle getStyle() const { return style; }
virtual Object writeToObject(XRef *xref) const = 0;
......@@ -296,8 +295,7 @@ protected:
AnnotBorderType type;
double width;
static const int DASH_LIMIT = 10; // implementation note 82 in Appendix H.
int dashLength;
double *dash;
std::vector<double> dash;
AnnotBorderStyle style;
};
......
......@@ -479,14 +479,12 @@ void CairoOutputDev::updateCTM(GfxState *state, double m11, double m12, double m
void CairoOutputDev::updateLineDash(GfxState *state)
{
double *dashPattern;
int dashLength;
double dashStart;
state->getLineDash(&dashPattern, &dashLength, &dashStart);
cairo_set_dash(cairo, dashPattern, dashLength, dashStart);
const std::vector<double> &dashPattern = state->getLineDash(&dashStart);
cairo_set_dash(cairo, dashPattern.data(), dashPattern.size(), dashStart);
if (cairo_shape) {
cairo_set_dash(cairo_shape, dashPattern, dashLength, dashStart);
cairo_set_dash(cairo_shape, dashPattern.data(), dashPattern.size(), dashStart);
}
}
......
......@@ -887,22 +887,13 @@ void Gfx::opConcat(Object args[], int numArgs)
void Gfx::opSetDash(Object args[], int numArgs)
{
Array *a;
int length;
double *dash;
int i;
a = args[0].getArray();
length = a->getLength();
if (length == 0) {
dash = nullptr;
} else {
dash = (double *)gmallocn(length, sizeof(double));
for (i = 0; i < length; ++i) {
dash[i] = a->get(i).getNumWithDefaultValue(0);
}
const Array *a = args[0].getArray();
int length = a->getLength();
std::vector<double> dash(length);
for (int i = 0; i < length; ++i) {
dash[i] = a->get(i).getNumWithDefaultValue(0);
}
state->setLineDash(dash, length, args[1].getNum());
state->setLineDash(std::move(dash), args[1].getNum());
out->updateLineDash(state);
}
......@@ -5146,8 +5137,6 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double
double x, y, sx, sy, tx, ty;
double m[6], bbox[4];
GfxColor color;
double *dash, *dash2;
int dashLength;
int i;
// this function assumes that we are in the default user space,
......@@ -5322,12 +5311,10 @@ void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor, double
out->updateStrokeColor(state);
state->setLineWidth(border->getWidth());
out->updateLineWidth(state);
dashLength = border->getDashLength();
dash = border->getDash();
if (border->getStyle() == AnnotBorder::borderDashed && dashLength > 0) {
dash2 = (double *)gmallocn(dashLength, sizeof(double));
memcpy(dash2, dash, dashLength * sizeof(double));
state->setLineDash(dash2, dashLength, 0);
const std::vector<double> &dash = border->getDash();
if (border->getStyle() == AnnotBorder::borderDashed && dash.size() > 0) {
std::vector<double> dash2 = dash;
state->setLineDash(std::move(dash2), 0);
out->updateLineDash(state);
}
//~ this doesn't currently handle the beveled and engraved styles
......
......@@ -6504,8 +6504,6 @@ GfxState::GfxState(double hDPIA, double vDPIA, const PDFRectangle *pageBox, int
transfer[0] = transfer[1] = transfer[2] = transfer[3] = nullptr;
lineWidth = 1;
lineDash = nullptr;
lineDashLength = 0;
lineDashStart = 0;
flatness = 1;
lineJoin = 0;
......@@ -6587,7 +6585,6 @@ GfxState::~GfxState()
delete transfer[i];
}
}
gfree(lineDash);
if (path) {
// this gets set to NULL by restore()
delete path;
......@@ -6646,12 +6643,7 @@ GfxState::GfxState(const GfxState *state, bool copyPath)
}
}
lineWidth = state->lineWidth;
lineDashLength = state->lineDashLength;
lineDash = nullptr;
if (lineDashLength > 0) {
lineDash = (double *)gmallocn(lineDashLength, sizeof(double));
memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double));
}
lineDash = state->lineDash;
lineDashStart = state->lineDashStart;
flatness = state->flatness;
lineJoin = state->lineJoin;
......@@ -6973,13 +6965,9 @@ void GfxState::setTransfer(Function **funcs)
}
}
void GfxState::setLineDash(double *dash, int length, double start)
void GfxState::setLineDash(std::vector<double> &&dash, double start)
{
if (lineDash) {
gfree(lineDash);
}
lineDash = dash;
lineDashLength = length;
lineDashStart = start;
}
......
......@@ -44,6 +44,7 @@
#include <cassert>
#include <map>
#include <memory>
#include <vector>
class Array;
class Gfx;
......@@ -1502,11 +1503,10 @@ public:
int getOverprintMode() const { return overprintMode; }
Function **getTransfer() { return transfer; }
double getLineWidth() const { return lineWidth; }
void getLineDash(double **dash, int *length, double *start)
const std::vector<double> &getLineDash(double *start)
{
*dash = lineDash;
*length = lineDashLength;
*start = lineDashStart;
return lineDash;
}
int getFlatness() const { return flatness; }
int getLineJoin() const { return lineJoin; }
......@@ -1588,7 +1588,7 @@ public:
void setOverprintMode(int op) { overprintMode = op; }
void setTransfer(Function **funcs);
void setLineWidth(double width) { lineWidth = width; }
void setLineDash(double *dash, int length, double start);
void setLineDash(std::vector<double> &&dash, double start);
void setFlatness(int flatness1) { flatness = flatness1; }
void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
void setLineCap(int lineCap1) { lineCap = lineCap1; }
......@@ -1750,8 +1750,7 @@ private:
// R,G,B,gray functions)
double lineWidth; // line width
double *lineDash; // line dash
int lineDashLength;
std::vector<double> lineDash; // line dash
double lineDashStart;
int flatness; // curve flatness
int lineJoin; // line join style
......
......@@ -3919,14 +3919,12 @@ void PSOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21,
void PSOutputDev::updateLineDash(GfxState *state)
{
double *dash;
double start;
int length, i;
state->getLineDash(&dash, &length, &start);
const std::vector<double> &dash = state->getLineDash(&start);
writePS("[");
for (i = 0; i < length; ++i) {
writePSFmt("{0:.6g}{1:w}", dash[i] < 0 ? 0 : dash[i], (i == length - 1) ? 0 : 1);
for (std::vector<double>::size_type i = 0; i < dash.size(); ++i) {
writePSFmt("{0:.6g}{1:w}", dash[i] < 0 ? 0 : dash[i], (i == dash.size() - 1) ? 0 : 1);
}
writePSFmt("] {0:.6g} d\n", start);
}
......
......@@ -53,13 +53,11 @@ void PreScanOutputDev::endPage() { }
void PreScanOutputDev::stroke(GfxState *state)
{
double *dash;
int dashLen;
double dashStart;
check(state->getStrokeColorSpace(), state->getStrokeColor(), state->getStrokeOpacity(), state->getBlendMode());
state->getLineDash(&dash, &dashLen, &dashStart);
if (dashLen != 0) {
const std::vector<double> &dash = state->getLineDash(&dashStart);
if (dash.size() != 0) {
gdi = false;
}
}
......
......@@ -1471,15 +1471,12 @@ void SplashOutputDev::updateCTM(GfxState *state, double m11, double m12, double
void SplashOutputDev::updateLineDash(GfxState *state)
{
double *dashPattern;
int dashLength;
double dashStart;
int i;
state->getLineDash(&dashPattern, &dashLength, &dashStart);
const std::vector<double> &dashPattern = state->getLineDash(&dashStart);
std::vector<SplashCoord> dash(dashLength);
for (i = 0; i < dashLength; ++i) {
std::vector<SplashCoord> dash(dashPattern.size());
for (std::vector<double>::size_type i = 0; i < dashPattern.size(); ++i) {
dash[i] = (SplashCoord)dashPattern[i];
if (dash[i] < 0) {
dash[i] = 0;
......
......@@ -240,22 +240,20 @@ void QPainterOutputDev::updateCTM(GfxState *state, double m11, double m12, doubl
void QPainterOutputDev::updateLineDash(GfxState *state)
{
double *dashPattern;
int dashLength;
double dashStart;
state->getLineDash(&dashPattern, &dashLength, &dashStart);
const std::vector<double> &dashPattern = state->getLineDash(&dashStart);
// Special handling for zero-length patterns, i.e., solid lines.
// Simply calling QPen::setDashPattern with an empty pattern does *not*
// result in a solid line. Rather, the current pattern is unchanged.
// See the implementation of the setDashPattern method in the file qpen.cpp.
if (dashLength == 0) {
if (dashPattern.empty()) {
m_currentPen.setStyle(Qt::SolidLine);
m_painter.top()->setPen(m_currentPen);
return;
}
QVector<qreal> pattern(dashLength);
QVector<qreal> pattern(dashPattern.size());
double scaling = state->getLineWidth();
// Negative line widths are not allowed, width 0 counts as 'one pixel width'.
......@@ -263,7 +261,7 @@ void QPainterOutputDev::updateLineDash(GfxState *state)
scaling = 1.0;
}
for (int i = 0; i < dashLength; ++i) {
for (std::vector<double>::size_type i = 0; i < dashPattern.size(); ++i) {
// pdf measures the dash pattern in dots, but Qt uses the
// line width as the unit.
pattern[i] = dashPattern[i] / scaling;
......
......@@ -10,7 +10,7 @@
* Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96@gmail.com>
* Copyright (C) 2018, 2019 Tobias Deiminger <haxtibal@posteo.de>
* Copyright (C) 2018 Carlos Garcia Campos <carlosgc@gnome.org>
* Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
* Copyright (C) 2020, 2022 Oliver Sander <oliver.sander@tu-dresden.de>
* Copyright (C) 2020 Katarina Behrens <Katarina.Behrens@cib.de>
* Copyright (C) 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de>
* Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden
......@@ -1702,13 +1702,12 @@ Annotation::Style Annotation::style() const
s.setWidth(border->getWidth());
s.setLineStyle((Annotation::LineStyle)(1 << border->getStyle()));
const int dashArrLen = border->getDashLength();
const double *dashArrData = border->getDash();
QVector<double> dashArrVect(dashArrLen);
for (int i = 0; i < dashArrLen; ++i) {
dashArrVect[i] = dashArrData[i];
}
s.setDashArray(dashArrVect);
const std::vector<double> &dashArray = border->getDash();
#if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0)
s.setDashArray(QVector<double>::fromStdVector(dashArray));
#else
s.setDashArray(QVector<double>(dashArray.begin(), dashArray.end()));
#endif
}
AnnotBorderEffect *border_effect;
......
......@@ -240,22 +240,20 @@ void QPainterOutputDev::updateCTM(GfxState *state, double m11, double m12, doubl
void QPainterOutputDev::updateLineDash(GfxState *state)
{
double *dashPattern;
int dashLength;
double dashStart;
state->getLineDash(&dashPattern, &dashLength, &dashStart);
const std::vector<double> &dashPattern = state->getLineDash(&dashStart);
// Special handling for zero-length patterns, i.e., solid lines.
// Simply calling QPen::setDashPattern with an empty pattern does *not*
// result in a solid line. Rather, the current pattern is unchanged.
// See the implementation of the setDashPattern method in the file qpen.cpp.
if (dashLength == 0) {
if (dashPattern.empty()) {
m_currentPen.setStyle(Qt::SolidLine);
m_painter.top()->setPen(m_currentPen);
return;
}
QVector<qreal> pattern(dashLength);
QVector<qreal> pattern(dashPattern.size());
double scaling = state->getLineWidth();
// Negative line widths are not allowed, width 0 counts as 'one pixel width'.
......@@ -263,7 +261,7 @@ void QPainterOutputDev::updateLineDash(GfxState *state)
scaling = 1.0;
}
for (int i = 0; i < dashLength; ++i) {
for (std::vector<double>::size_type i = 0; i < dashPattern.size(); ++i) {
// pdf measures the dash pattern in dots, but Qt uses the
// line width as the unit.
pattern[i] = dashPattern[i] / scaling;
......
......@@ -10,7 +10,7 @@
* Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96@gmail.com>
* Copyright (C) 2018, 2019 Tobias Deiminger <haxtibal@posteo.de>
* Copyright (C) 2018 Carlos Garcia Campos <carlosgc@gnome.org>
* Copyright (C) 2020, 2021 Oliver Sander <oliver.sander@tu-dresden.de>
* Copyright (C) 2020-2022 Oliver Sander <oliver.sander@tu-dresden.de>
* Copyright (C) 2020 Katarina Behrens <Katarina.Behrens@cib.de>
* Copyright (C) 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de>
* Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by Technische Universität Dresden
......@@ -1341,13 +1341,8 @@ Annotation::Style Annotation::style() const
s.setWidth(border->getWidth());
s.setLineStyle((Annotation::LineStyle)(1 << border->getStyle()));
const int dashArrLen = border->getDashLength();
const double *dashArrData = border->getDash();
QVector<double> dashArrVect(dashArrLen);
for (int i = 0; i < dashArrLen; ++i) {
dashArrVect[i] = dashArrData[i];
}
s.setDashArray(dashArrVect);
const std::vector<double> &dashArray = border->getDash();
s.setDashArray(QVector<double>(dashArray.begin(), dashArray.end()));
}
AnnotBorderEffect *border_effect;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment