Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Commit

Permalink
Refactoring of Label.propagateFonts() (#3052)
Browse files Browse the repository at this point in the history
* Refactor propagateFonts(), first working version. Default font  for 'mono' is now 'monospace'

* Tested and cleaned up refactoring changes
  • Loading branch information
wimrijnders authored and yotamberk committed May 13, 2017
1 parent 1673980 commit e422c34
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 112 deletions.
2 changes: 1 addition & 1 deletion lib/network/modules/NodesHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class NodesHandler {
mono: {
mod: '',
size: 15, // px
face: 'courier new',
face: 'monospace',
vadjust: 2
}
},
Expand Down
234 changes: 123 additions & 111 deletions lib/network/modules/components/shared/Label.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,124 +126,136 @@ class Label {
}
}


/**
* Collapse the font options for the multi-font to single objects, from
* the chain of option objects passed.
*
* If an option for a specific multi-font is not present, the parent
* option is checked for the given option.
*
* NOTE: naming of 'groupOptions' is a misnomer; the actual value passed
* is the new values to set from setOptions().
*/
propagateFonts(options, groupOptions, defaultOptions) {
if (this.fontOptions.multi) {
let mods = [ 'bold', 'ital', 'boldital', 'mono' ];
for (const mod of mods) {
let optionsFontMod;
if (options.font) {
optionsFontMod = options.font[mod];
}
if (typeof optionsFontMod === 'string') {
let modOptionsArray = optionsFontMod.split(" ");
this.fontOptions[mod].size = modOptionsArray[0].replace("px","");
this.fontOptions[mod].face = modOptionsArray[1];
this.fontOptions[mod].color = modOptionsArray[2];
this.fontOptions[mod].vadjust = this.fontOptions.vadjust;
this.fontOptions[mod].mod = defaultOptions.font[mod].mod;
} else {
// We need to be crafty about loading the modded fonts. We want as
// much 'natural' versatility as we can get, so a simple global
// change propagates in an expected way, even if not stictly logical.

// face: We want to capture any direct settings and overrides, but
// fall back to the base font if there aren't any. We make a
// special exception for mono, since we probably don't want to
// sync to a the base font face.
//
// if the mod face is in the node's options, use it
// else if the mod face is in the global options, use it
// else if the face is in the global options, use it
// else use the base font's face.
if (optionsFontMod && optionsFontMod.hasOwnProperty('face')) {
this.fontOptions[mod].face = optionsFontMod.face;
} else if (groupOptions.font && groupOptions.font[mod] &&
groupOptions.font[mod].hasOwnProperty('face')) {
this.fontOptions[mod].face = groupOptions.font[mod].face;
} else if (mod === 'mono') {
this.fontOptions[mod].face = defaultOptions.font[mod].face;
} else if (groupOptions.font &&
groupOptions.font.hasOwnProperty('face')) {
this.fontOptions[mod].face = groupOptions.font.face;
} else {
this.fontOptions[mod].face = this.fontOptions.face;
}
if (!this.fontOptions.multi) return;

// color: this is handled just like the face.
if (optionsFontMod && optionsFontMod.hasOwnProperty('color')) {
this.fontOptions[mod].color = optionsFontMod.color;
} else if (groupOptions.font && groupOptions.font[mod] &&
groupOptions.font[mod].hasOwnProperty('color')) {
this.fontOptions[mod].color = groupOptions.font[mod].color;
} else if (groupOptions.font &&
groupOptions.font.hasOwnProperty('color')) {
this.fontOptions[mod].color = groupOptions.font.color;
} else {
this.fontOptions[mod].color = this.fontOptions.color;
}
/**
* Get property value from options.font[mod][property] if present.
* If mod not passed, use property value from options.font[property].
*
* @return value if found, null otherwise.
*/
var getP = function(options, mod, property) {
if (!options.font) return null;

// mod: this is handled just like the face, except we never grab the
// base font's mod. We know they're in the defaultOptions, and unless
// we've been steered away from them, we use the default.
if (optionsFontMod && optionsFontMod.hasOwnProperty('mod')) {
this.fontOptions[mod].mod = optionsFontMod.mod;
} else if (groupOptions.font && groupOptions.font[mod] &&
groupOptions.font[mod].hasOwnProperty('mod')) {
this.fontOptions[mod].mod = groupOptions.font[mod].mod;
} else if (groupOptions.font &&
groupOptions.font.hasOwnProperty('mod')) {
this.fontOptions[mod].mod = groupOptions.font.mod;
} else {
this.fontOptions[mod].mod = defaultOptions.font[mod].mod;
}
var opt = options.font;

// size: It's important that we size up defaults similarly if we're
// using default faces unless overriden. We want to preserve the
// ratios closely - but if faces have changed, all bets are off.
//
// if the mod size is in the node's options, use it
// else if the mod size is in the global options, use it
// else if the mod face is the same as the default and the base face
// is the same as the default, scale the mod size using the same
// ratio
// else if the size is in the global options, use it
// else use the base font's size.
if (optionsFontMod && optionsFontMod.hasOwnProperty('size')) {
this.fontOptions[mod].size = optionsFontMod.size;
} else if (groupOptions.font && groupOptions.font[mod] &&
groupOptions.font[mod].hasOwnProperty('size')) {
this.fontOptions[mod].size = groupOptions.font[mod].size;
} else if ((this.fontOptions[mod].face === defaultOptions.font[mod].face) &&
(this.fontOptions.face === defaultOptions.font.face)) {
let ratio = this.fontOptions.size / Number(defaultOptions.font.size);
this.fontOptions[mod].size = defaultOptions.font[mod].size * ratio;
} else if (groupOptions.font &&
groupOptions.font.hasOwnProperty('size')) {
this.fontOptions[mod].size = groupOptions.font.size;
} else {
this.fontOptions[mod].size = this.fontOptions.size;
}
if (mod) {
if (!opt[mod]) return null;
opt = opt[mod];
}

// vadjust: this is handled just like the size.
if (optionsFontMod && optionsFontMod.hasOwnProperty('vadjust')) {
this.fontOptions[mod].vadjust = optionsFontMod.vadjust;
} else if (groupOptions.font &&
groupOptions.font[mod] && groupOptions.font[mod].hasOwnProperty('vadjust')) {
this.fontOptions[mod].vadjust = groupOptions.font[mod].vadjust;
} else if ((this.fontOptions[mod].face === defaultOptions.font[mod].face) &&
(this.fontOptions.face === defaultOptions.font.face)) {
let ratio = this.fontOptions.size / Number(defaultOptions.font.size);
this.fontOptions[mod].vadjust = defaultOptions.font[mod].vadjust * Math.round(ratio);
} else if (groupOptions.font &&
groupOptions.font.hasOwnProperty('vadjust')) {
this.fontOptions[mod].vadjust = groupOptions.font.vadjust;
} else {
this.fontOptions[mod].vadjust = this.fontOptions.vadjust;
}
if (opt.hasOwnProperty(property)) {
return opt[property];
}

return null;
};


let mods = [ 'bold', 'ital', 'boldital', 'mono' ];
for (const mod of mods) {
let modOptions = this.fontOptions[mod];
let modDefaults = defaultOptions.font[mod];

let optionsFontMod;
if (options.font) {
optionsFontMod = options.font[mod];
}

if (typeof optionsFontMod === 'string') {
let modOptionsArray = optionsFontMod.split(" ");
modOptions.size = modOptionsArray[0].replace("px","");
modOptions.face = modOptionsArray[1];
modOptions.color = modOptionsArray[2];
modOptions.vadjust = this.fontOptions.vadjust;
modOptions.mod = modDefaults.mod;
} else {

// We need to be crafty about loading the modded fonts. We want as
// much 'natural' versatility as we can get, so a simple global
// change propagates in an expected way, even if not stictly logical.

// face: We want to capture any direct settings and overrides, but
// fall back to the base font if there aren't any. We make a
// special exception for mono, since we probably don't want to
// sync to a the base font face.
modOptions.face =
getP(options , mod, 'face') ||
getP(groupOptions, mod, 'face') ||
(mod === 'mono'? modDefaults.face:null ) ||
getP(groupOptions, null, 'face') ||
this.fontOptions.face
;

// color: this is handled just like the face, except for specific default for 'mono'
modOptions.color =
getP(options , mod, 'color') ||
getP(groupOptions, mod, 'color') ||
getP(groupOptions, null, 'color') ||
this.fontOptions.color
;

// mod: this is handled just like the face, except we never grab the
// base font's mod. We know they're in the defaultOptions, and unless
// we've been steered away from them, we use the default.
modOptions.mod =
getP(options , mod, 'mod') ||
getP(groupOptions, mod, 'mod') ||
getP(groupOptions, null, 'mod') ||
modDefaults.mod
;


// It's important that we size up defaults similarly if we're
// using default faces unless overriden. We want to preserve the
// ratios closely - but if faces have changed, all bets are off.
let ratio;

// NOTE: Following condition always fails, because modDefaults
// has no explicit font property. This is deliberate, see
// var's 'NodesHandler.defaultOptions.font[mod]'.
// However, I want to keep the original logic while refactoring;
// it appears to be working fine even if ratio is never set.
// TODO: examine if this is a bug, fix if necessary.
//
if ((modOptions.face === modDefaults.face) &&
(this.fontOptions.face === defaultOptions.font.face)) {

ratio = this.fontOptions.size / Number(defaultOptions.font.size);
}
this.fontOptions[mod].size = Number(this.fontOptions[mod].size);
this.fontOptions[mod].vadjust = Number(this.fontOptions[mod].vadjust);


modOptions.size =
getP(options , mod, 'size') ||
getP(groupOptions, mod, 'size') ||
(ratio? modDefaults.size * ratio: null) || // Scale the mod size using the same ratio
getP(groupOptions, null, 'size') ||
this.fontOptions.size
;

modOptions.vadjust =
getP(options , mod, 'vadjust') ||
getP(groupOptions, mod, 'vadjust') ||
(ratio? modDefaults.vadjust * Math.round(ratio): null) || // Scale it using the same ratio
this.fontOptions.vadjust
;

}

modOptions.size = Number(modOptions.size);
modOptions.vadjust = Number(modOptions.vadjust);
}
}

Expand Down

0 comments on commit e422c34

Please sign in to comment.