Extend font family possibilities

To fix in the future: memory usage of font-styled item labels
This commit is contained in:
abakkk 2020-08-05 23:30:25 +02:00
parent 80e2955f8c
commit c78f5e82da
3 changed files with 65 additions and 19 deletions

40
area.js
View File

@ -54,7 +54,7 @@ const ManipulationNames = { 100: "Move", 101: "Resize", 102: "Mirror" };
var Tools = Object.assign({}, Shapes, Manipulations);
var ToolNames = Object.assign({}, ShapeNames, ManipulationNames);
var FontGenericNames = { 0: 'Theme', 1: 'Sans-Serif', 2: 'Serif', 3: 'Monospace', 4: 'Cursive', 5: 'Fantasy' };
var FontGenericFamilies = ['Sans-Serif', 'Serif', 'Monospace', 'Cursive', 'Fantasy'];
// DrawingArea is the widget in which we draw, thanks to Cairo.
// It creates and manages a DrawingElement for each "brushstroke".
@ -82,7 +82,6 @@ var DrawingArea = new Lang.Class({
this.currentElement = null;
this.currentTool = Shapes.NONE;
this.currentImage = 0;
this.currentFontGeneric = 0;
this.isSquareArea = false;
this.hasGrid = false;
this.hasBackground = false;
@ -145,6 +144,24 @@ var DrawingArea = new Lang.Class({
return images;
},
get currentFontFamily() {
return this._currentFontFamily || this.currentThemeFontFamily;
},
set currentFontFamily(fontFamily) {
this._currentFontFamily = fontFamily;
},
get fontFamilies() {
if (!this._fontFamilies) {
let pangoFontFamilies = Elements.getPangoFontFamilies().filter(family => {
return family != this.currentThemeFontFamily && FontGenericFamilies.indexOf(family) == -1;
});
this._fontFamilies = [this.currentThemeFontFamily].concat(FontGenericFamilies, pangoFontFamilies);
}
return this._fontFamilies;
},
vfunc_repaint: function() {
let cr = this.get_context();
@ -198,6 +215,7 @@ var DrawingArea = new Lang.Class({
this.colors[i] = this.colors[i].alpha ? this.colors[i] : this.colors[0];
}
this.currentColor = this.currentColor || this.colors[1];
this._fontFamilies = null;
// SVG does not support 'Ultra-heavy' weight (1000)
this.newThemeAttributes.FontWeight = Math.min(this.newThemeAttributes.FontWeight, 900);
this.newThemeAttributes.LineWidth = (this.newThemeAttributes.LineWidth > 0) ? this.newThemeAttributes.LineWidth : 3;
@ -545,7 +563,7 @@ var DrawingArea = new Lang.Class({
color: this.currentColor.to_string(),
eraser: eraser,
font: {
family: (this.currentFontGeneric == 0 ? this.currentThemeFontFamily : FontGenericNames[this.currentFontGeneric]),
family: this.currentFontFamily,
weight: this.currentFontWeight,
style: this.currentFontStyle,
stretch: this.currentFontStretch,
@ -913,13 +931,13 @@ var DrawingArea = new Lang.Class({
},
toggleFontFamily: function() {
this.currentFontGeneric = this.currentFontGeneric == 5 ? 0 : this.currentFontGeneric + 1;
let currentFontFamily = this.currentFontGeneric == 0 ? this.currentThemeFontFamily : FontGenericNames[this.currentFontGeneric];
let index = Math.max(0, this.fontFamilies.indexOf(this.currentFontFamily));
this.currentFontFamily = (index == this.fontFamilies.length - 1) ? 0 : this.fontFamilies[index + 1];
if (this.currentElement && this.currentElement.font) {
this.currentElement.font.family = currentFontFamily;
this.currentElement.font.family = this.currentFontFamily;
this._redisplay();
}
this.emit('show-osd', null, `<span font_family="${currentFontFamily}">${_(currentFontFamily)}</span>`, "", -1, false);
this.emit('show-osd', null, `<span font_family="${this.currentFontFamily}">${_(this.currentFontFamily)}</span>`, "", -1, false);
},
toggleTextAlignment: function() {
@ -978,7 +996,7 @@ var DrawingArea = new Lang.Class({
this.stageKeyReleasedHandler = global.stage.connect('key-release-event', this._onStageKeyReleased.bind(this));
this.keyPressedHandler = this.connect('key-press-event', this._onKeyPressed.bind(this));
this.buttonPressedHandler = this.connect('button-press-event', this._onButtonPressed.bind(this));
this._onKeyboardPopupMenuHandler = this.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
this.keyboardPopupMenuHandler = this.connect('popup-menu', this._onKeyboardPopupMenu.bind(this));
this.scrollHandler = this.connect('scroll-event', this._onScroll.bind(this));
this.get_parent().set_background_color(this.reactive && this.hasBackground ? this.activeBackgroundColor : null);
this._updateStyle();
@ -1001,9 +1019,9 @@ var DrawingArea = new Lang.Class({
this.disconnect(this.buttonPressedHandler);
this.buttonPressedHandler = null;
}
if (this._onKeyboardPopupMenuHandler) {
this.disconnect(this._onKeyboardPopupMenuHandler);
this._onKeyboardPopupMenuHandler = null;
if (this.keyboardPopupMenuHandler) {
this.disconnect(this.keyboardPopupMenuHandler);
this.keyboardPopupMenuHandler = null;
}
if (this.motionHandler) {
this.disconnect(this.motionHandler);

View File

@ -46,6 +46,10 @@ var FontStyleNames = reverseEnumeration(Pango.Style);
var FontStretchNames = reverseEnumeration(Pango.Stretch);
var FontVariantNames = reverseEnumeration(Pango.Variant);
var getPangoFontFamilies = function() {
return PangoCairo.font_map_get_default().list_families().map(fontFamily => fontFamily.get_name()).sort((a,b) => a.localeCompare(b));
};
const SVG_DEBUG_SUPERPOSES_CAIRO = false;
const RADIAN = 180 / Math.PI; // degree
const INVERSION_CIRCLE_RADIUS = 12; // px

40
menu.js
View File

@ -56,6 +56,9 @@ const FILLRULE_EVENODD_ICON_PATH = ICON_DIR.get_child('fillrule-evenodd-symbolic
const DASHED_LINE_ICON_PATH = ICON_DIR.get_child('dashed-line-symbolic.svg').get_path();
const FULL_LINE_ICON_PATH = ICON_DIR.get_child('full-line-symbolic.svg').get_path();
// 150 labels with font-family style take ~15Mo
const FONT_FAMILY_STYLE = true;
const getActor = function(object) {
return GS_VERSION < '3.33.0' ? object.actor : object;
};
@ -180,9 +183,7 @@ var DrawingMenu = new Lang.Class({
this.lineSection = lineSection;
let fontSection = new PopupMenu.PopupMenuSection();
let FontGenericNamesCopy = Object.create(Area.FontGenericNames);
FontGenericNamesCopy[0] = this.area.currentThemeFontFamily;
this._addSubMenuItem(fontSection, 'font-x-generic-symbolic', FontGenericNamesCopy, this.area, 'currentFontGeneric');
this._addFontFamilySubMenuItem(fontSection, 'font-x-generic-symbolic');
this._addSubMenuItem(fontSection, 'format-text-bold-symbolic', Elements.FontWeightNames, this.area, 'currentFontWeight');
this._addSubMenuItem(fontSection, 'format-text-italic-symbolic', Elements.FontStyleNames, this.area, 'currentFontStyle');
this._addSwitchItem(fontSection, _("Right aligned"), 'format-justify-left-symbolic', 'format-justify-right-symbolic', this.area, 'currentTextRightAligned');
@ -342,9 +343,7 @@ var DrawingMenu = new Lang.Class({
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
for (let i in obj) {
let text;
if (targetProperty == 'currentFontGeneric')
text = `<span font_family="${obj[i]}">${_(obj[i])}</span>`;
else if (targetProperty == 'currentFontWeight')
if (targetProperty == 'currentFontWeight')
text = `<span font_weight="${i}">${_(obj[i])}</span>`;
else if (targetProperty == 'currentFontStyle')
text = `<span font_style="${obj[i].toLowerCase()}">${_(obj[i])}</span>`;
@ -391,7 +390,6 @@ var DrawingMenu = new Lang.Class({
this.area.currentColor = this.area.colors[iCaptured];
item.icon.set_style(`color:${this.area.currentColor.to_string().slice(0, 7)};`);
});
colorItem.label.get_clutter_text().set_use_markup(true);
// Foreground color markup is not displayed since 3.36, use style instead but the transparency is lost.
colorItem.label.set_style(`color:${this.area.colors[i].to_string().slice(0, 7)};`);
}
@ -401,6 +399,32 @@ var DrawingMenu = new Lang.Class({
return item;
},
_addFontFamilySubMenuItem: function(menu, icon) {
let item = new PopupMenu.PopupSubMenuMenuItem(this.area.currentFontFamily, true);
item.icon.set_icon_name(icon);
item.menu.itemActivated = () => {
item.menu.close();
};
item.menu.openOld = item.menu.open;
item.menu.open = (animate) => {
if (!item.menu.isOpen && item.menu.isEmpty()) {
this.area.fontFamilies.forEach(family => {
let subItem = item.menu.addAction(_(family), () => {
item.label.set_text(_(family));
this.area.currentFontFamily = family;
});
if (FONT_FAMILY_STYLE)
subItem.label.set_style(`font-family:${family}`);
});
}
item.menu.openOld();
};
menu.addMenuItem(item);
},
_addDrawingNameItem: function(menu) {
this.drawingNameMenuItem = new PopupMenu.PopupMenuItem('', { reactive: false, activate: false });
this.drawingNameMenuItem.setSensitive(false);
@ -420,8 +444,8 @@ var DrawingMenu = new Lang.Class({
_addOpenDrawingSubMenuItem: function(menu) {
let item = new PopupMenu.PopupSubMenuMenuItem(_("Open drawing"), true);
this.openDrawingSubMenuItem = item;
this.openDrawingSubMenuItem.setSensitive(Boolean(Files.getJsons().length));
this.openDrawingSubMenu = item.menu;
item.setSensitive(Boolean(Files.getJsons().length));
item.icon.set_icon_name('document-open-symbolic');
item.menu.itemActivated = () => {