color and font

* Pass Clutter color and Pango fontDescription objects to elements, not strings.
* Do not use the color format '#rrggbbaa' in svg since it is not supported in GNOME 3.24.
This commit is contained in:
abakkk 2020-09-15 00:29:02 +02:00
parent b63c1e9ffa
commit 42b4c9c00c
3 changed files with 37 additions and 36 deletions

34
area.js
View File

@ -64,12 +64,14 @@ Object.defineProperty(Tools, 'getNameOf', { enumerable: false });
const getClutterColorFromString = function(string, fallback) { const getClutterColorFromString = function(string, fallback) {
let [success, color] = Clutter.Color.from_string(string); let [success, color] = Clutter.Color.from_string(string);
color.string = string; color.toString = () => string;
if (success) if (success)
return color; return color;
log(`${Me.metadata.uuid}: "${string}" color cannot be parsed.`); log(`${Me.metadata.uuid}: "${string}" color cannot be parsed.`);
return Clutter.Color.get_static(Clutter.StaticColor[fallback]); color = Clutter.Color.get_static(Clutter.StaticColor[fallback.toUpperCase()]);
color.toString = () => fallback.slice(0, 1).toUpperCase() + fallback.slice(1);
return color;
}; };
// DrawingArea is the widget in which we draw, thanks to Cairo. // DrawingArea is the widget in which we draw, thanks to Cairo.
@ -150,7 +152,7 @@ var DrawingArea = new Lang.Class({
set currentPalette(palette) { set currentPalette(palette) {
this._currentPalette = palette; this._currentPalette = palette;
this.colors = palette[1].map(colorString => getClutterColorFromString(colorString, 'WHITE')); this.colors = palette[1].map(colorString => getClutterColorFromString(colorString, 'white'));
if (!this.colors[0]) if (!this.colors[0])
this.colors.push(Clutter.Color.get_static(Clutter.StaticColor.WHITE)); this.colors.push(Clutter.Color.get_static(Clutter.StaticColor.WHITE));
}, },
@ -252,9 +254,9 @@ var DrawingArea = new Lang.Class({
this.squareAreaSize = Me.drawingSettings.get_uint('square-area-size'); this.squareAreaSize = Me.drawingSettings.get_uint('square-area-size');
} }
this.areaBackgroundColor = getClutterColorFromString(Me.drawingSettings.get_string('background-color'), 'BLACK'); this.areaBackgroundColor = getClutterColorFromString(Me.drawingSettings.get_string('background-color'), 'black');
this.gridColor = getClutterColorFromString(Me.drawingSettings.get_string('grid-color'), 'GRAY'); this.gridColor = getClutterColorFromString(Me.drawingSettings.get_string('grid-color'), 'gray');
if (Me.drawingSettings.get_boolean('grid-line-auto')) { if (Me.drawingSettings.get_boolean('grid-line-auto')) {
this.gridLineSpacing = Math.round(this.monitor.width / (5 * GRID_TILES_HORIZONTAL_NUMBER)); this.gridLineSpacing = Math.round(this.monitor.width / (5 * GRID_TILES_HORIZONTAL_NUMBER));
this.gridLineWidth = this.gridLineSpacing / 20; this.gridLineWidth = this.gridLineSpacing / 20;
@ -601,9 +603,9 @@ var DrawingArea = new Lang.Class({
if (this.currentTool == Shapes.TEXT) { if (this.currentTool == Shapes.TEXT) {
this.currentElement = new Elements.DrawingElement({ this.currentElement = new Elements.DrawingElement({
shape: this.currentTool, shape: this.currentTool,
color: this.currentColor.to_string(), color: this.currentColor,
eraser: eraser, eraser: eraser,
font: this.currentFont.to_string(), font: this.currentFont.copy(),
// Translators: initial content of the text area // Translators: initial content of the text area
text: pgettext("text-area-content", "Text"), text: pgettext("text-area-content", "Text"),
textRightAligned: this.currentTextRightAligned, textRightAligned: this.currentTextRightAligned,
@ -612,7 +614,7 @@ var DrawingArea = new Lang.Class({
} else if (this.currentTool == Shapes.IMAGE) { } else if (this.currentTool == Shapes.IMAGE) {
this.currentElement = new Elements.DrawingElement({ this.currentElement = new Elements.DrawingElement({
shape: this.currentTool, shape: this.currentTool,
color: this.currentColor.to_string(), color: this.currentColor,
eraser: eraser, eraser: eraser,
image: this.currentImage, image: this.currentImage,
operator: this.currentOperator, operator: this.currentOperator,
@ -621,7 +623,7 @@ var DrawingArea = new Lang.Class({
} else { } else {
this.currentElement = new Elements.DrawingElement({ this.currentElement = new Elements.DrawingElement({
shape: this.currentTool, shape: this.currentTool,
color: this.currentColor.to_string(), color: this.currentColor,
eraser: eraser, eraser: eraser,
fill: this.fill, fill: this.fill,
fillRule: this.currentFillRule, fillRule: this.currentFillRule,
@ -900,11 +902,11 @@ var DrawingArea = new Lang.Class({
this.currentColor = this.colors[index]; this.currentColor = this.colors[index];
if (this.currentElement) { if (this.currentElement) {
this.currentElement.color = this.currentColor.to_string(); this.currentElement.color = this.currentColor;
this._redisplay(); this._redisplay();
} }
// Foreground color markup is not displayed since 3.36, use style instead but the transparency is lost. // Foreground color markup is not displayed since 3.36, use style instead but the transparency is lost.
this.emit('show-osd', Files.Icons.COLOR, this.currentColor.string || this.currentColor.to_string(), this.currentColor.to_string().slice(0, 7), -1, false); this.emit('show-osd', Files.Icons.COLOR, String(this.currentColor), this.currentColor.to_string().slice(0, 7), -1, false);
}, },
selectTool: function(tool) { selectTool: function(tool) {
@ -1107,6 +1109,10 @@ var DrawingArea = new Lang.Class({
let elements = []; let elements = [];
elements.push(...JSON.parse(json.contents).map(object => { elements.push(...JSON.parse(json.contents).map(object => {
if (object.color)
object.color = getClutterColorFromString(object.color, 'white');
if (object.font && typeof object.font == 'string')
object.font = Pango.FontDescription.from_string(object.font);
if (object.image) if (object.image)
object.image = new Files.Image(object.image); object.image = new Files.Image(object.image);
return new Elements.DrawingElement(object); return new Elements.DrawingElement(object);
@ -1137,7 +1143,7 @@ var DrawingArea = new Lang.Class({
let content = `<svg viewBox="0 0 ${this.width} ${this.height}" ${prefixes}>`; let content = `<svg viewBox="0 0 ${this.width} ${this.height}" ${prefixes}>`;
if (SVG_DEBUG_EXTENDS) if (SVG_DEBUG_EXTENDS)
content = `<svg viewBox="${-this.width} ${-this.height} ${2 * this.width} ${2 * this.height}" xmlns="http://www.w3.org/2000/svg">`; content = `<svg viewBox="${-this.width} ${-this.height} ${2 * this.width} ${2 * this.height}" xmlns="http://www.w3.org/2000/svg">`;
let backgroundColorString = this.hasBackground ? this.areaBackgroundColor.to_string() : 'transparent'; let backgroundColorString = this.hasBackground ? String(this.areaBackgroundColor) : 'transparent';
if (backgroundColorString != 'transparent') { if (backgroundColorString != 'transparent') {
content += `\n <rect id="background" width="100%" height="100%" fill="${backgroundColorString}"/>`; content += `\n <rect id="background" width="100%" height="100%" fill="${backgroundColorString}"/>`;
} }
@ -1219,6 +1225,10 @@ var DrawingArea = new Lang.Class({
return; return;
this.elements.push(...JSON.parse(json.contents).map(object => { this.elements.push(...JSON.parse(json.contents).map(object => {
if (object.color)
object.color = getClutterColorFromString(object.color, 'white');
if (object.font && typeof object.font == 'string')
object.font = Pango.FontDescription.from_string(object.font);
if (object.image) if (object.image)
object.image = new Files.Image(object.image); object.image = new Files.Image(object.image);
return new Elements.DrawingElement(object); return new Elements.DrawingElement(object);

View File

@ -81,20 +81,19 @@ const _DrawingElement = new Lang.Class({
if (params.transformations === undefined) if (params.transformations === undefined)
this.transformations = []; this.transformations = [];
if (params.font && typeof params.font != 'string') { if (params.font && !(params.font instanceof Pango.FontDescription)) {
// compatibility with v6.2- // compatibility with v6.2-
if (params.font.weight === 0) if (params.font.weight === 0)
this.font.weight = 400; this.font.weight = 400;
else if (params.font.weight === 1) else if (params.font.weight === 1)
this.font.weight = 700; this.font.weight = 700;
let font = new Pango.FontDescription(); this.font = new Pango.FontDescription();
['family', 'weight', 'style', 'stretch', 'variant'].forEach(attribute => { ['family', 'weight', 'style', 'stretch', 'variant'].forEach(attribute => {
if (params.font[attribute] !== undefined) if (params.font[attribute] !== undefined)
try { try {
font[`set_${attribute}`](params.font[attribute]); this.font[`set_${attribute}`](params.font[attribute]);
} catch(e) {} } catch(e) {}
}); });
this.font = font.to_string();
} }
if (params.transform && params.transform.center) { if (params.transform && params.transform.center) {
@ -114,7 +113,7 @@ const _DrawingElement = new Lang.Class({
toJSON: function() { toJSON: function() {
return { return {
shape: this.shape, shape: this.shape,
color: this.color, color: this.color.toString(),
line: this.line, line: this.line,
dash: this.dash, dash: this.dash,
fill: this.fill, fill: this.fill,
@ -126,11 +125,8 @@ const _DrawingElement = new Lang.Class({
}, },
buildCairo: function(cr, params) { buildCairo: function(cr, params) {
if (this.color) { if (this.color)
let [success, color] = Clutter.Color.from_string(this.color); Clutter.cairo_set_source_color(cr, this.color);
if (success)
Clutter.cairo_set_source_color(cr, color);
}
if (this.showSymmetryElement) { if (this.showSymmetryElement) {
let transformation = this.lastTransformation; let transformation = this.lastTransformation;
@ -256,7 +252,7 @@ const _DrawingElement = new Lang.Class({
return inElement; return inElement;
}, },
buildSVG: function(bgColor) { buildSVG: function(bgcolorString) {
let transAttribute = ''; let transAttribute = '';
this.transformations.slice(0).reverse().forEach(transformation => { this.transformations.slice(0).reverse().forEach(transformation => {
transAttribute += transAttribute ? ' ' : ' transform="'; transAttribute += transAttribute ? ' ' : ' transform="';
@ -284,13 +280,13 @@ const _DrawingElement = new Lang.Class({
}); });
transAttribute += transAttribute ? '"' : ''; transAttribute += transAttribute ? '"' : '';
return this._drawSvg(transAttribute); return this._drawSvg(transAttribute, bgcolorString);
}, },
_drawSvg: function(transAttribute) { _drawSvg: function(transAttribute, bgcolorString) {
let row = "\n "; let row = "\n ";
let points = this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100]); let points = this.points.map((point) => [Math.round(point[0]*100)/100, Math.round(point[1]*100)/100]);
let color = this.eraser ? bgColor : this.color; let color = this.eraser ? bgcolorString : this.color.toString();
let fill = this.fill && !this.isStraightLine; let fill = this.fill && !this.isStraightLine;
let attributes = ''; let attributes = '';
@ -605,18 +601,13 @@ const TextElement = new Lang.Class({
Name: 'DrawOnYourScreenTextElement', Name: 'DrawOnYourScreenTextElement',
Extends: _DrawingElement, Extends: _DrawingElement,
_init: function(params) {
this.parent(params);
this.font = Pango.FontDescription.from_string(this.font);
},
toJSON: function() { toJSON: function() {
// The font size is useless because it is always computed from the points during cairo/svg building. // The font size is useless because it is always computed from the points during cairo/svg building.
this.font.unset_fields(Pango.FontMask.SIZE); this.font.unset_fields(Pango.FontMask.SIZE);
return { return {
shape: this.shape, shape: this.shape,
color: this.color, color: this.color.toString(),
eraser: this.eraser, eraser: this.eraser,
transformations: this.transformations, transformations: this.transformations,
text: this.text, text: this.text,
@ -683,10 +674,10 @@ const TextElement = new Lang.Class({
return cr.inFill(x, y); return cr.inFill(x, y);
}, },
_drawSvg: function(transAttribute) { _drawSvg: function(transAttribute, bgcolorString) {
let row = "\n "; let row = "\n ";
let [x, y, height] = [Math.round(this.x*100)/100, Math.round(this.y*100)/100, Math.round(this.height*100)/100]; let [x, y, height] = [Math.round(this.x*100)/100, Math.round(this.y*100)/100, Math.round(this.height*100)/100];
let color = this.eraser ? bgColor : this.color; let color = this.eraser ? bgcolorString : this.color.toString();
let attributes = ''; let attributes = '';
if (this.points.length == 2) { if (this.points.length == 2) {
@ -760,7 +751,7 @@ const ImageElement = new Lang.Class({
toJSON: function() { toJSON: function() {
return { return {
shape: this.shape, shape: this.shape,
color: this.color, color: this.color.toString(),
fill: this.fill, fill: this.fill,
eraser: this.eraser, eraser: this.eraser,
transformations: this.transformations, transformations: this.transformations,

View File

@ -495,7 +495,7 @@ var DrawingMenu = new Lang.Class({
this.colorSubMenu.removeAll(); this.colorSubMenu.removeAll();
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => { GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
this.area.colors.forEach(color => { this.area.colors.forEach(color => {
let text = color.string || color.to_string(); let text = String(color);
let subItem = this.colorSubMenu.addAction(text, () => { let subItem = this.colorSubMenu.addAction(text, () => {
this.area.currentColor = color; this.area.currentColor = color;
this.colorItem.icon.set_style(`color:${color.to_string().slice(0, 7)};`); this.colorItem.icon.set_style(`color:${color.to_string().slice(0, 7)};`);