Doctor's Cot 2.0 - Mightyfrong/gallifreyan-translation-helper GitHub Wiki
setup.js
Defines basic variables
- const glyphSize = 50; // radius of glyphs
- const dc2Consonants = new cotConsonants(); // initates consonant class
- const dc2Vowels = new cotVowels(); // initates vowel class
function cotKeyboard(appendTo, writeTo, keys) creates an onscreen keyboard to type ipa-characters. arguments are the elements where to display the keyboard, the element where typed characters should be inserted and the keys as an two-dimensional array of rows and columns.
function createKeyboard() will be called to initate the creation of the keyboard. since it is possible to have different keyboard layouts this function decides which keyboard is to be displayed and clears the former const alternativeKeyboard is an object for keyboards that will differ from the official ipa-keys, e.g. english. if some day other keyboards will be official they can easily implemented here with another top-level-key:
{
en: {
consonants: [
[ //row
["displayed character", "ipa-character"],
/*...*/
],
/*...*/
],
vowels: [ //row
[
["html-tags are allowed here", "ipa-character"],
/*...*/
],
/*...*/
]
}
doctorsCotGlyphs.js
Contains the construction dictionaries
like other styles Doctor's Cot has a tabular structure of characters alignes within base-rows and decorator-columns. this system distinguishes beween consonants and vowels though. therefore there are two types of classes.
export class cotConsonants {
constructor() {
this.base = {
/* example: { // name of group
contains: [...], // array of characters for which the handling and properties apply
baserad: ..., // the total inner radius decorator should attach to, important for single and double lined bases
outerline: ..., // lineweight for outer line
innerline: ..., // lineweight for inner line
draw: function (ctx, x, y, r){ // position of items to be placed and radius
SVGRenderingContext-draw instructions...
}
}*/
},
this.decorators= {
/* example: { // name of group
draw: function (ctx, x, y, r, lineweight, tilt){ // position of items to be placed, radius, lineweight and tilt
SVGRenderingContext-draw instructions...
}
}*/
}
}
getBase(char) { // return name of base the given character is assigned to
let rtrn = false;
Object.keys(this.base).forEach(row => {
if (includes(this.base[row].contains, char)) rtrn = row;
});
return rtrn;
}
getDeco(char) {} // similar to getBase
keyCollection() {
let rows = [];
Object.keys(this.base).forEach(row => {
let columns = [];
Object.keys(this.base[row].contains).forEach(key => {
columns.push([this.base[row].contains[key], this.base[row].contains[key]]);
});
rows.push(columns);
});
return rows;
}
}
export class cotVowels {
constructor() {
this.lines = {
ɑ: {
contains: ["ɑ", "i", "u", "a", "y"], // array of characters
outerline: 1, // lineweight for outer line
innerline: 0 // lineweight for inner line
},
/* ... */
};
this.shape = {
ɑ: {
contains: ["ɑ", "e", "ɛ", "ʊ", "ɯ", "œ"],
draw: function (ctx, x, y, r, lines, former) {
...SVGRenderingContext-draw instructions...
}
},
/* ... */
}
}
getLines(){} getShape(){} and keyCollection(){} like consonants
render.js
Recurring Variables Within Global Scope
- width: width of the output canvas
- height: height of the output canvas
- x: current x coordinate for drawing, representing the groups center coordinate
- y: current y coordinate for drawing, representing the words baseline
- glyph: glyph dimensions-object
- groupedInput: global variable for input to be updated
Translation
render(input) is the main wrapper for the algorithm and is passed the actual input. It sets up an array of characters to process later, determines the amount of character stacking and sets the canvas size according to the number of (grouped) characters.
The initial coordinates for the words baseline are set and the general draw object initiated.
Then the array of characters is processed for each word and each group of characters. Grouping of characters makes resizing of the base necessary. The index for the current position within the group is determined and used as a resizing factor and the character is drawn.
Grouping (Doctor's Cot)
doctorsCot2Grouped.groups(input) returns a multidimensional array of grouped characters. It initiates the sentence array and loops through the whitespace-splitted input. The word group is initiated. The following loop iterates over each character of the word, sets the current character, occasionally overrides single characters to double ones (th, ng) and corrects the index in this case.
As long as the former group has less items as the set amount characters will be added. Otherwise the current character initiates a new group.
The group is then pushed to the last word.
doctorsCot2Grouped.resetOffset(currentGroup) resets primarily the resizing factor of stacked characters and stores the groups content.
doctorsCot2Grouped.setOffset() sets the resizing for stackes consonants to be displayed as inner circle. It also sets the carriage return to true to have the characters drawn at the same x-position on the canvas.
Character Drawing (Doctors' Cot)
doctorsCot2Draw(ctx, letter, grouped) actually draws a character to the canvas. X and y coordiantes are set. If not grouped the x-"pointer" is set to the next characters position, if the end of the viewport is reached the next line is set.
Since the actual drawing instructions are part of the cotConsonants- and cotVowels-objects these are simply called by the passed character. Also the tilt-factor is set.
let tilt = .25 - .0625 * (grouped.offset + 1);
// draw outer circle
if (currentbase) dc2Consonants.base[currentbase].draw(ctx, x, y, glyphSize * grouped.resize, tilt);
// draw decorators
if (currentdeco) dc2Consonants.decorators[currentdeco].draw(ctx, x, y, glyphSize * dc2Consonants.base[currentbase].baserad, dc2Consonants.base[currentbase].innerline, tilt);
//draw inner circle if next character in group is not a consonant (or it's a single letter)
if (currentbase && !dc2Consonants.getBase(grouped.group[grouped.offset + 1]))
dc2Consonants.base[currentbase].draw(ctx, x, y, glyphSize * .4, tilt);
Finally above the letter/group the respective ipa-characters are drawn.