Skip to content

Instantly share code, notes, and snippets.

@admannon
Last active September 21, 2024 13:22
Show Gist options
  • Save admannon/700168ec388e8cbfc7fe5f840f7473c4 to your computer and use it in GitHub Desktop.
Save admannon/700168ec388e8cbfc7fe5f840f7473c4 to your computer and use it in GitHub Desktop.
Thai Text Support for RPG Maker MV & MZ
//=============================================================================
// ThaiTextSupport.js
// This code is licensed under the terms of the MIT license
//=============================================================================
/*:
* @plugindesc
* Fix font render that contain upper or/and lower glypts in message box.
* @author Admannon
*
* @help This plugin does not provide plugin commands.
*/
(function () {
// Intl.Segmenter polyfill
const Segmenter =
Intl.Segmenter ||
(() => {
if (!Intl.v8BreakIterator) {
throw new Error("unsupported segmenter");
}
function _granularityToV8Type(granularity) {
switch (granularity) {
case "word":
case "sentence":
case "line":
return granularity;
default:
return "character";
}
}
return class Segmenter {
constructor(locales, { granularity } = {}) {
this._v8Instance = Intl.v8BreakIterator(locales ? [locales] : undefined, {
type: _granularityToV8Type(granularity),
});
}
segment(text) {
this._v8Instance.adoptText(text);
let instance = this._v8Instance;
let start = instance.first();
return {
*[Symbol.iterator]() {
while (start !== -1) {
let next = instance.next();
if (next === -1) break;
yield {
segment: text.slice(start, next),
index: text.current,
input: text,
};
start = next;
}
},
};
}
};
})();
// Segmenter Object
const iterator = new Segmenter("th");
function makeGraphemeProxy(text) {
const graphemes = [...iterator.segment(text)].map((graphemeObj) => graphemeObj.segment);
const handler = {
get({ value }, accessorName) {
const graphemeAccessor = graphemes[accessorName];
if (typeof graphemeAccessor == "function") {
return (...arguments) => {
const result = graphemeAccessor.call(graphemes, ...arguments);
return Array.isArray(result) ? result.join("") : result;
};
}
if (graphemeAccessor) {
return graphemeAccessor;
}
const accessor = value[accessorName];
return typeof accessor == "function" ? accessor.bind(value) : accessor;
},
};
return new Proxy({ value: text }, handler);
}
const WindowBasePrototypeConvertEscapeCharacters = Window_Base.prototype.convertEscapeCharacters;
Window_Base.prototype.convertEscapeCharacters = function (text) {
text = WindowBasePrototypeConvertEscapeCharacters.call(this, text);
text = makeGraphemeProxy(text);
return text;
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment