|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import {getGlobalMetrics} from "./fontMetrics"; |
|
import type {FontMetrics} from "./fontMetrics"; |
|
import type {StyleInterface} from "./Style"; |
|
|
|
const sizeStyleMap = [ |
|
|
|
|
|
[1, 1, 1], |
|
[2, 1, 1], |
|
[3, 1, 1], |
|
[4, 2, 1], |
|
[5, 2, 1], |
|
[6, 3, 1], |
|
[7, 4, 2], |
|
[8, 6, 3], |
|
[9, 7, 6], |
|
[10, 8, 7], |
|
[11, 10, 9], |
|
]; |
|
|
|
const sizeMultipliers = [ |
|
|
|
|
|
0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.2, 1.44, 1.728, 2.074, 2.488, |
|
]; |
|
|
|
const sizeAtStyle = function(size: number, style: StyleInterface): number { |
|
return style.size < 2 ? size : sizeStyleMap[size - 1][style.size - 1]; |
|
}; |
|
|
|
|
|
export type FontWeight = "textbf" | "textmd" | ""; |
|
export type FontShape = "textit" | "textup" | ""; |
|
|
|
export type OptionsData = { |
|
style: StyleInterface; |
|
color?: string | void; |
|
size?: number; |
|
textSize?: number; |
|
phantom?: boolean; |
|
font?: string; |
|
fontFamily?: string; |
|
fontWeight?: FontWeight; |
|
fontShape?: FontShape; |
|
sizeMultiplier?: number; |
|
maxSize: number; |
|
minRuleThickness: number; |
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Options { |
|
style: StyleInterface; |
|
color: string | void; |
|
size: number; |
|
textSize: number; |
|
phantom: boolean; |
|
|
|
|
|
|
|
font: string; |
|
fontFamily: string; |
|
fontWeight: FontWeight; |
|
fontShape: FontShape; |
|
sizeMultiplier: number; |
|
maxSize: number; |
|
minRuleThickness: number; |
|
_fontMetrics: FontMetrics | void; |
|
|
|
|
|
|
|
|
|
static BASESIZE: number = 6; |
|
|
|
constructor(data: OptionsData) { |
|
this.style = data.style; |
|
this.color = data.color; |
|
this.size = data.size || Options.BASESIZE; |
|
this.textSize = data.textSize || this.size; |
|
this.phantom = !!data.phantom; |
|
this.font = data.font || ""; |
|
this.fontFamily = data.fontFamily || ""; |
|
this.fontWeight = data.fontWeight || ''; |
|
this.fontShape = data.fontShape || ''; |
|
this.sizeMultiplier = sizeMultipliers[this.size - 1]; |
|
this.maxSize = data.maxSize; |
|
this.minRuleThickness = data.minRuleThickness; |
|
this._fontMetrics = undefined; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
extend(extension: $Shape<OptionsData>): Options { |
|
const data = { |
|
style: this.style, |
|
size: this.size, |
|
textSize: this.textSize, |
|
color: this.color, |
|
phantom: this.phantom, |
|
font: this.font, |
|
fontFamily: this.fontFamily, |
|
fontWeight: this.fontWeight, |
|
fontShape: this.fontShape, |
|
maxSize: this.maxSize, |
|
minRuleThickness: this.minRuleThickness, |
|
}; |
|
|
|
for (const key in extension) { |
|
if (extension.hasOwnProperty(key)) { |
|
data[key] = extension[key]; |
|
} |
|
} |
|
|
|
return new Options(data); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
havingStyle(style: StyleInterface): Options { |
|
if (this.style === style) { |
|
return this; |
|
} else { |
|
return this.extend({ |
|
style: style, |
|
size: sizeAtStyle(this.textSize, style), |
|
}); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
havingCrampedStyle(): Options { |
|
return this.havingStyle(this.style.cramp()); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
havingSize(size: number): Options { |
|
if (this.size === size && this.textSize === size) { |
|
return this; |
|
} else { |
|
return this.extend({ |
|
style: this.style.text(), |
|
size: size, |
|
textSize: size, |
|
sizeMultiplier: sizeMultipliers[size - 1], |
|
}); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
havingBaseStyle(style: StyleInterface): Options { |
|
style = style || this.style.text(); |
|
const wantSize = sizeAtStyle(Options.BASESIZE, style); |
|
if (this.size === wantSize && this.textSize === Options.BASESIZE |
|
&& this.style === style) { |
|
return this; |
|
} else { |
|
return this.extend({ |
|
style: style, |
|
size: wantSize, |
|
}); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
havingBaseSizing(): Options { |
|
let size; |
|
switch (this.style.id) { |
|
case 4: |
|
case 5: |
|
size = 3; |
|
break; |
|
case 6: |
|
case 7: |
|
size = 1; |
|
break; |
|
default: |
|
size = 6; |
|
} |
|
return this.extend({ |
|
style: this.style.text(), |
|
size: size, |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
withColor(color: string): Options { |
|
return this.extend({ |
|
color: color, |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
withPhantom(): Options { |
|
return this.extend({ |
|
phantom: true, |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
withFont(font: string): Options { |
|
return this.extend({ |
|
font, |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
withTextFontFamily(fontFamily: string): Options { |
|
return this.extend({ |
|
fontFamily, |
|
font: "", |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
withTextFontWeight(fontWeight: FontWeight): Options { |
|
return this.extend({ |
|
fontWeight, |
|
font: "", |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
withTextFontShape(fontShape: FontShape): Options { |
|
return this.extend({ |
|
fontShape, |
|
font: "", |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
sizingClasses(oldOptions: Options): Array<string> { |
|
if (oldOptions.size !== this.size) { |
|
return ["sizing", "reset-size" + oldOptions.size, "size" + this.size]; |
|
} else { |
|
return []; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
baseSizingClasses(): Array<string> { |
|
if (this.size !== Options.BASESIZE) { |
|
return ["sizing", "reset-size" + this.size, "size" + Options.BASESIZE]; |
|
} else { |
|
return []; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
fontMetrics(): FontMetrics { |
|
if (!this._fontMetrics) { |
|
this._fontMetrics = getGlobalMetrics(this.size); |
|
} |
|
return this._fontMetrics; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
getColor(): string | void { |
|
if (this.phantom) { |
|
return "transparent"; |
|
} else { |
|
return this.color; |
|
} |
|
} |
|
} |
|
|
|
export default Options; |
|
|