|
@ -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) { |
|
|
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); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|