Merge pull request #593 from andreasb242/fill-stroke

Load / Save and draw fill. UI not yet there.
presentation
andreasb242 7 years ago committed by GitHub
commit 646eb1815d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 366
      po/cs.po
  2. 2566
      po/de.po
  3. 366
      po/pl.po
  4. 366
      po/zh.po
  5. 366
      po/zh_HK.po
  6. 366
      po/zh_TW.po
  7. 22
      src/control/xojfile/LoadHandler.cpp
  8. 125
      src/control/xojfile/SaveHandler.cpp
  9. 11
      src/control/xojfile/SaveHandler.h
  10. 16
      src/control/xojfile/XojExportHandler.cpp
  11. 5
      src/control/xojfile/XojExportHandler.h
  12. 36
      src/model/Stroke.cpp
  13. 27
      src/model/Stroke.h
  14. 1
      src/util/serializing/ObjectOutputStream.cpp
  15. 39
      src/view/DocumentView.cpp
  16. 2
      src/view/DocumentView.h

File diff suppressed because it is too large Load Diff

2566
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -491,10 +491,8 @@ void LoadHandler::parseStroke()
this->layer->addElement(this->stroke);
const char* width = LoadHandlerHelper::getAttrib("width", false, this);
char* ptr = NULL;
char* tmpptr = NULL;
double val = 0;
char* ptr = NULL;
stroke->setWidth(g_ascii_strtod(width, &ptr));
if (ptr == width)
{
@ -504,7 +502,8 @@ void LoadHandler::parseStroke()
while (*ptr != 0)
{
val = g_ascii_strtod(ptr, &tmpptr);
char* tmpptr = NULL;
double val = g_ascii_strtod(ptr, &tmpptr);
if (tmpptr == ptr)
{
break;
@ -522,17 +521,24 @@ void LoadHandler::parseStroke()
stroke->setColor(color);
/** read stroke timestamps (xopp fileformat) */
const char* fn = LoadHandlerHelper::getAttrib("fn",true,this);
int ts;
const char* fn = LoadHandlerHelper::getAttrib("fn", true, this);
if (fn != NULL)
{
stroke->setAudioFilename(fn);
}
if (LoadHandlerHelper::getAttribInt("ts",true,this,ts))
int ts = 0;
if (LoadHandlerHelper::getAttribInt("ts", true, this, ts))
{
stroke->setTimestamp(ts);
}
int fill = -1;
if (LoadHandlerHelper::getAttribInt("fill", true, this, fill))
{
stroke->setFill(fill);
}
const char* tool = LoadHandlerHelper::getAttrib("tool", false, this);
if (strcmp("eraser", tool) == 0)
@ -557,7 +563,7 @@ void LoadHandler::parseStroke()
* we've read just before.
* Afterwards, clean the read timestamp data.
*/
if(loadedFilename.length() != 0)
if (loadedFilename.length() != 0)
{
this->stroke->setTimestamp(loadedTimeStamp);
this->stroke->setAudioFilename(loadedFilename);

@ -119,70 +119,93 @@ void SaveHandler::writeTimestamp(Stroke* s, XmlPointNode* stroke)
stroke->setAttrib("fn",s->getAudioFilename());
}
void SaveHandler::visitLayer(XmlNode* page, Layer* l)
void SaveHandler::visitStroke(XmlPointNode* stroke, Stroke* s)
{
XOJ_CHECK_TYPE(SaveHandler);
XmlNode* layer = new XmlNode("layer");
page->addChild(layer);
for(Element* e : *l->getElements())
StrokeTool t = s->getToolType();
unsigned char alpha = 0xff;
if (t == STROKE_TOOL_PEN)
{
if (e->getType() == ELEMENT_STROKE)
{
Stroke* s = (Stroke*) e;
XmlPointNode* stroke = new XmlPointNode("stroke");
layer->addChild(stroke);
stroke->setAttrib("tool", "pen");
writeTimestamp(s, stroke);
}
else if (t == STROKE_TOOL_ERASER)
{
stroke->setAttrib("tool", "eraser");
}
else if (t == STROKE_TOOL_HIGHLIGHTER)
{
stroke->setAttrib("tool", "highlighter");
alpha = 0x7f;
}
else
{
g_warning("Unknown stroke tool type: %i", t);
stroke->setAttrib("tool", "pen");
}
StrokeTool t = s->getToolType();
stroke->setAttrib("color", getColorStr(s->getColor(), alpha).c_str());
unsigned char alpha = 0xff;
int pointCount = s->getPointCount();
if (t == STROKE_TOOL_PEN)
{
stroke->setAttrib("tool", "pen");
writeTimestamp(s,stroke);
}
else if (t == STROKE_TOOL_ERASER)
{
stroke->setAttrib("tool", "eraser");
}
else if (t == STROKE_TOOL_HIGHLIGHTER)
{
stroke->setAttrib("tool", "highlighter");
alpha = 0x7f;
}
else
{
g_warning("Unknown stroke tool type: %i", t);
stroke->setAttrib("tool", "pen");
}
for (int i = 0; i < pointCount; i++)
{
Point p = s->getPoint(i);
stroke->addPoint(&p);
}
stroke->setAttrib("color", getColorStr(s->getColor(), alpha).c_str());
if (s->hasPressure())
{
double* values = new double[pointCount + 1];
values[0] = s->getWidth();
for (int i = 0; i < pointCount; i++)
{
values[i + 1] = s->getPoint(i).z;
}
int pointCount = s->getPointCount();
stroke->setAttrib("width", values, pointCount);
}
else
{
stroke->setAttrib("width", s->getWidth());
}
for (int i = 0; i < pointCount; i++)
{
Point p = s->getPoint(i);
stroke->addPoint(&p);
}
visitStrokeExtended(stroke, s);
}
if (s->hasPressure())
{
double* values = new double[pointCount + 1];
values[0] = s->getWidth();
for (int i = 0; i < pointCount; i++)
{
values[i + 1] = s->getPoint(i).z;
}
/**
* Export the fill attributes
*/
void SaveHandler::visitStrokeExtended(XmlPointNode* stroke, Stroke* s)
{
XOJ_CHECK_TYPE(SaveHandler);
stroke->setAttrib("width", values, pointCount);
}
else
{
stroke->setAttrib("width", s->getWidth());
}
if (s->getFill() == -1)
{
// no fill to save
return;
}
stroke->setAttrib("fill", s->getFill());
}
void SaveHandler::visitLayer(XmlNode* page, Layer* l)
{
XOJ_CHECK_TYPE(SaveHandler);
XmlNode* layer = new XmlNode("layer");
page->addChild(layer);
for(Element* e : *l->getElements())
{
if (e->getType() == ELEMENT_STROKE)
{
Stroke* s = (Stroke*) e;
XmlPointNode* stroke = new XmlPointNode("stroke");
layer->addChild(stroke);
visitStroke(stroke, s);
}
else if (e->getType() == ELEMENT_TEXT)
{

@ -35,9 +35,16 @@ public:
string getErrorMessage();
protected:
void visitPage(XmlNode* root, PageRef p, Document* doc, int id);
static string getColorStr(int c, unsigned char alpha = 0xff);
void visitLayer(XmlNode* page, Layer* l);
virtual void visitPage(XmlNode* root, PageRef p, Document* doc, int id);
virtual void visitLayer(XmlNode* page, Layer* l);
virtual void visitStroke(XmlPointNode* stroke, Stroke* s);
/**
* Export the fill attributes
*/
virtual void visitStrokeExtended(XmlPointNode* stroke, Stroke* s);
virtual void writeHeader();
virtual void writeSolidBackground(XmlNode* background, PageRef p);

@ -35,12 +35,22 @@ XojExportHandler::~XojExportHandler()
XOJ_RELEASE_TYPE(XojExportHandler);
}
/**
* Export the fill attributes
*/
void XojExportHandler::visitStrokeExtended(XmlPointNode* stroke, Stroke* s)
{
XOJ_CHECK_TYPE(XojExportHandler);
// Fill is not exported in .xoj
}
void XojExportHandler::writeHeader()
{
XOJ_CHECK_TYPE(XojExportHandler);
this->root->setAttrib("creator", PROJECT_STRING);
// Keept this version on 2, as this is anyway not read by Xournal
// Keep this version on 2, as this is anyway not read by Xournal
this->root->setAttrib("fileversion", "2");
this->root->addChild(new XmlTextNode("title", "Xournal document (Compatibility) - see " PROJECT_URL));
}
@ -63,5 +73,5 @@ void XojExportHandler::writeSolidBackground(XmlNode* background, PageRef p)
void XojExportHandler::writeTimestamp(Stroke* s, XmlPointNode* stroke)
{
XOJ_CHECK_TYPE(XojExportHandler);
//Do nothing since timestamp are not supported by Xournal
}
// Do nothing since timestamp are not supported by Xournal
}

@ -23,6 +23,11 @@ public:
virtual ~XojExportHandler();
protected:
/**
* Export the fill attributes
*/
virtual void visitStrokeExtended(XmlPointNode* stroke, Stroke* s);
virtual void writeHeader();
virtual void writeSolidBackground(XmlNode* background, PageRef p);
virtual void writeTimestamp(Stroke* s, XmlPointNode* stroke);

@ -26,6 +26,7 @@ Stroke::Stroke()
this->timestamp = 0;
this->eraseable = NULL;
this->fill = -1;
}
Stroke::~Stroke()
@ -37,7 +38,7 @@ Stroke::~Stroke()
this->pointCount = 0;
this->pointAllocCount = 0;
this->timestamp=0;
this->timestamp = 0;
XOJ_RELEASE_TYPE(Stroke);
}
@ -52,6 +53,7 @@ Stroke* Stroke::cloneStroke() const
s->setWidth(this->getWidth());
s->setAudioFilename(this->getAudioFilename());
s->setTimestamp(this->getTimestamp());
s->setFill(this->getFill());
s->allocPointSize(this->pointCount);
memcpy(s->points, this->points, this->pointCount * sizeof(Point));
@ -83,6 +85,8 @@ void Stroke::serialize(ObjectOutputStream& out)
out.writeInt(this->timestamp);
out.writeInt(fill);
out.writeData(this->points, this->pointCount, sizeof(Point));
out.endObject();
@ -104,6 +108,8 @@ void Stroke::readSerialized(ObjectInputStream& in)
this->timestamp = in.readInt();
this->fill = in.readInt();
if (this->points)
{
g_free(this->points);
@ -140,6 +146,34 @@ int Stroke::getTimestamp() const
return this->timestamp;
}
/**
* Option to fill the shape:
* -1: The shape is not filled
* 255: The shape is fully opaque filled
* ...
* 1: The shape is nearly fully transparent filled
*/
int Stroke::getFill() const
{
XOJ_CHECK_TYPE(Stroke);
return fill;
}
/**
* Option to fill the shape:
* -1: The shape is not filled
* 255: The shape is fully opaque filled
* ...
* 1: The shape is nearly fully transparent filled
*/
void Stroke::setFill(int fill)
{
XOJ_CHECK_TYPE(Stroke);
this->fill = fill;
}
void Stroke::setWidth(double width)
{
XOJ_CHECK_TYPE(Stroke);

@ -42,6 +42,24 @@ public:
void setAudioFilename(string fn);
string getAudioFilename() const;
/**
* Option to fill the shape:
* -1: The shape is not filled
* 255: The shape is fully opaque filled
* ...
* 1: The shape is nearly fully transparent filled
*/
int getFill() const;
/**
* Option to fill the shape:
* -1: The shape is not filled
* 255: The shape is fully opaque filled
* ...
* 1: The shape is nearly fully transparent filled
*/
void setFill(int fill);
void addPoint(Point p);
void setLastPoint(double x, double y);
void setFirstPoint(double x, double y);
@ -107,4 +125,13 @@ private:
string audioFilename;
EraseableStroke* eraseable;
/**
* Option to fill the shape:
* -1: The shape is not filled
* 255: The shape is fully opaque filled
* ...
* 1: The shape is nearly fully transparent filled
*/
int fill;
};

@ -4,6 +4,7 @@
#include "Serializeable.h"
ObjectOutputStream::ObjectOutputStream(ObjectEncoding* encoder)
: encoder(NULL)
{
XOJ_INIT_TYPE(ObjectOutputStream);

@ -95,6 +95,34 @@ void DocumentView::drawEraseableStroke(cairo_t* cr, Stroke* s)
e->draw(cr, this->lX, this->lY, this->width, this->height);
}
void DocumentView::drawFillStroke(cairo_t* cr, Stroke* s)
{
XOJ_CHECK_TYPE(DocumentView);
// Set the color and transparency
applyColor(cr, s, s->getFill());
ArrayIterator<Point> points = s->pointIterator();
if (points.hasNext())
{
Point p = points.next();
cairo_move_to(cr, p.x, p.y);
}
else
{
return;
}
while (points.hasNext())
{
Point p = points.next();
cairo_line_to(cr, p.x, p.y);
}
cairo_fill(cr);
}
void DocumentView::drawStroke(cairo_t* cr, Stroke* s, int startPoint, double scaleFactor, bool changeSource)
{
XOJ_CHECK_TYPE(DocumentView);
@ -110,6 +138,17 @@ void DocumentView::drawStroke(cairo_t* cr, Stroke* s, int startPoint, double sca
if (changeSource)
{
///////////////////////////////////////////////////////
// Fill stroke
///////////////////////////////////////////////////////
if (s->getFill() != -1)
{
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
drawFillStroke(cr, s);
}
if (s->getToolType() == STROKE_TOOL_HIGHLIGHTER ||
(s->getAudioFilename().length() == 0 && this->markAudioStroke))
{

@ -49,6 +49,8 @@ public:
void drawStroke(cairo_t* cr, Stroke* s, int startPoint = 0, double scaleFactor = 1, bool changeSource = true);
void drawEraseableStroke(cairo_t* cr, Stroke* s);
void drawFillStroke(cairo_t* cr, Stroke* s);
static void applyColor(cairo_t* cr, Stroke* s);
static void applyColor(cairo_t* cr, int c, int alpha = 255);
static void applyColor(cairo_t* cr, Element* e, int alpha = 255);

Loading…
Cancel
Save