colored SVG images
Color (fill) SVG images by pressing the `Shift` key.
This commit is contained in:
parent
532b9242c9
commit
3c67bf3398
8
area.js
8
area.js
|
|
@ -603,7 +603,7 @@ var DrawingArea = new Lang.Class({
|
|||
this._redisplay();
|
||||
},
|
||||
|
||||
_startDrawing: function(stageX, stageY, eraser) {
|
||||
_startDrawing: function(stageX, stageY, shiftPressed) {
|
||||
let [success, startX, startY] = this.transform_stage_point(stageX, stageY);
|
||||
|
||||
if (!success)
|
||||
|
|
@ -617,7 +617,7 @@ var DrawingArea = new Lang.Class({
|
|||
this.currentElement = new Elements.DrawingElement({
|
||||
shape: this.currentTool,
|
||||
color: this.currentColor,
|
||||
eraser: eraser,
|
||||
eraser: shiftPressed,
|
||||
font: this.currentFont.copy(),
|
||||
// Translators: initial content of the text area
|
||||
text: pgettext("text-area-content", "Text"),
|
||||
|
|
@ -628,7 +628,7 @@ var DrawingArea = new Lang.Class({
|
|||
this.currentElement = new Elements.DrawingElement({
|
||||
shape: this.currentTool,
|
||||
color: this.currentColor,
|
||||
eraser: eraser,
|
||||
colored: shiftPressed,
|
||||
image: this.currentImage,
|
||||
points: []
|
||||
});
|
||||
|
|
@ -636,7 +636,7 @@ var DrawingArea = new Lang.Class({
|
|||
this.currentElement = new Elements.DrawingElement({
|
||||
shape: this.currentTool,
|
||||
color: this.currentColor,
|
||||
eraser: eraser,
|
||||
eraser: shiftPressed,
|
||||
fill: this.fill,
|
||||
fillRule: this.currentFillRule,
|
||||
line: { lineWidth: this.currentLineWidth, lineJoin: this.currentLineJoin, lineCap: this.currentLineCap },
|
||||
|
|
|
|||
|
|
@ -771,7 +771,7 @@ const ImageElement = new Lang.Class({
|
|||
return {
|
||||
shape: this.shape,
|
||||
color: this.color,
|
||||
eraser: this.eraser,
|
||||
colored: this.colored,
|
||||
transformations: this.transformations,
|
||||
image: this.image,
|
||||
preserveAspectRatio: this.preserveAspectRatio,
|
||||
|
|
@ -791,7 +791,7 @@ const ImageElement = new Lang.Class({
|
|||
return;
|
||||
|
||||
cr.save();
|
||||
this.image.setCairoSource(cr, x, y, width, height, this.preserveAspectRatio);
|
||||
this.image.setCairoSource(cr, x, y, width, height, this.preserveAspectRatio, this.colored ? this.color.toJSON() : null);
|
||||
cr.rectangle(x, y, width, height);
|
||||
cr.fill();
|
||||
cr.restore();
|
||||
|
|
@ -813,14 +813,15 @@ const ImageElement = new Lang.Class({
|
|||
_drawSvg: function(transAttribute) {
|
||||
let points = this.points;
|
||||
let row = "\n ";
|
||||
let attributes = this.eraser ? `class="eraser" ` : '';
|
||||
let attributes = '';
|
||||
|
||||
if (points.length == 2) {
|
||||
attributes += `fill="none"`;
|
||||
let base64 = this.image.getBase64ForColor(this.colored ? this.color.toJSON() : null);
|
||||
row += `<image ${attributes} x="${Math.min(points[0][0], points[1][0])}" y="${Math.min(points[0][1], points[1][1])}" ` +
|
||||
`width="${Math.abs(points[1][0] - points[0][0])}" height="${Math.abs(points[1][1] - points[0][1])}"${transAttribute} ` +
|
||||
`preserveAspectRatio="${this.preserveAspectRatio ? 'xMinYMin' : 'none'}" ` +
|
||||
`id="${this.image.displayName}" xlink:href="data:${this.image.contentType};base64,${this.image.base64}"/>`;
|
||||
`id="${this.image.displayName}" xlink:href="data:${this.image.contentType};base64,${base64}"/>`;
|
||||
}
|
||||
|
||||
return row;
|
||||
|
|
|
|||
49
files.js
49
files.js
|
|
@ -83,6 +83,18 @@ Object.keys(ThemedIconNames).forEach(key => {
|
|||
});
|
||||
});
|
||||
|
||||
const replaceColor = function (contents, color) {
|
||||
if (contents instanceof Uint8Array)
|
||||
contents = ByteArray.toString(contents);
|
||||
else
|
||||
contents = contents.toString();
|
||||
|
||||
return contents.replace(/fill(?=="transparent"|="none"|:transparent|:none)/gi, 'filll')
|
||||
.replace(/fill="[^"]+"/gi, `fill="${color}"`)
|
||||
.replace(/fill:[^";]+/gi, `fill:${color};`)
|
||||
.replace(/filll/gi, 'fill');
|
||||
};
|
||||
|
||||
// Wrapper around image data. If not subclassed, it is used when loading in the area an image element for a drawing file (.json)
|
||||
// and it takes { displayName, contentType, base64, hash } as params.
|
||||
var Image = new Lang.Class({
|
||||
|
|
@ -122,6 +134,14 @@ var Image = new Lang.Class({
|
|||
this._base64 = base64;
|
||||
},
|
||||
|
||||
getBase64ForColor: function(color) {
|
||||
if (!color || this.contentType != 'image/svg+xml')
|
||||
return this.base64;
|
||||
|
||||
let contents = GLib.base64_decode(this.base64);
|
||||
return GLib.base64_encode(replaceColor(contents, color));
|
||||
},
|
||||
|
||||
// hash is not used
|
||||
get hash() {
|
||||
if (!this._hash)
|
||||
|
|
@ -133,7 +153,22 @@ var Image = new Lang.Class({
|
|||
this._hash = hash;
|
||||
},
|
||||
|
||||
get pixbuf() {
|
||||
getBytesForColor: function(color) {
|
||||
if (!color || this.contentType != 'image/svg+xml')
|
||||
return this.bytes;
|
||||
|
||||
let contents = this.bytes.get_data();
|
||||
return new GLib.Bytes(replaceColor(contents, color));
|
||||
},
|
||||
|
||||
getPixbuf: function(color) {
|
||||
if (color) {
|
||||
let stream = Gio.MemoryInputStream.new_from_bytes(this.getBytesForColor(color));
|
||||
let pixbuf = GdkPixbuf.Pixbuf.new_from_stream(stream, null);
|
||||
stream.close(null);
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
if (!this._pixbuf) {
|
||||
let stream = Gio.MemoryInputStream.new_from_bytes(this.bytes);
|
||||
this._pixbuf = GdkPixbuf.Pixbuf.new_from_stream(stream, null);
|
||||
|
|
@ -142,16 +177,16 @@ var Image = new Lang.Class({
|
|||
return this._pixbuf;
|
||||
},
|
||||
|
||||
getPixbufAtScale: function(width, height) {
|
||||
let stream = Gio.MemoryInputStream.new_from_bytes(this.bytes);
|
||||
getPixbufAtScale: function(width, height, color) {
|
||||
let stream = Gio.MemoryInputStream.new_from_bytes(this.getBytesForColor(color));
|
||||
let pixbuf = GdkPixbuf.Pixbuf.new_from_stream_at_scale(stream, width, height, true, null);
|
||||
stream.close(null);
|
||||
return pixbuf;
|
||||
},
|
||||
|
||||
setCairoSource: function(cr, x, y, width, height, preserveAspectRatio) {
|
||||
let pixbuf = preserveAspectRatio ? this.getPixbufAtScale(width, height)
|
||||
: this.pixbuf.scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR);
|
||||
setCairoSource: function(cr, x, y, width, height, preserveAspectRatio, color) {
|
||||
let pixbuf = preserveAspectRatio ? this.getPixbufAtScale(width, height, color)
|
||||
: this.getPixbuf(color).scale_simple(width, height, GdkPixbuf.InterpType.BILINEAR);
|
||||
Gdk.cairo_set_source_pixbuf(cr, pixbuf, x, y);
|
||||
}
|
||||
});
|
||||
|
|
@ -552,7 +587,7 @@ var Jsons = {
|
|||
|
||||
var getDateString = function() {
|
||||
let date = GLib.DateTime.new_now_local();
|
||||
return `${date.format("%F")} ${date.format("%X")}`;
|
||||
return `${date.format("%F")} ${date.format("%T")}`;
|
||||
};
|
||||
|
||||
var saveSvg = function(content) {
|
||||
|
|
|
|||
2
menu.js
2
menu.js
|
|
@ -315,8 +315,6 @@ var DrawingMenu = new Lang.Class({
|
|||
this.lineSection.actor.visible = !isText && !isImage;
|
||||
this.fontSection.actor.visible = isText;
|
||||
this.imageSection.actor.visible = isImage;
|
||||
this.colorItem.setSensitive(!isImage);
|
||||
this.paletteItem.setSensitive(!isImage);
|
||||
this.fillItem.setSensitive(!isText && !isImage);
|
||||
this.fillSection.setSensitive(!isText && !isImage);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue