Jetbrains Projectorのデフォルトフォントだと日本語表示が微妙なので別のフォントを埋め込む
追記
- 2021/05/20: projector-client commit:8e89968 で日本語入力に対応したようです。
まだリリース前なので、試す場合のために別の記事を用意しました。
- 2021/05/02: projector-server 1.1.4でデフォルトフォントがNotoになりました。(CHANGELOG.md - 1.1.4)
はじめに
JetbrainsのBlogを眺めていたら新製品としてProjectorが紹介されていました。
The JetBrains Blog: Access Your IDE Remotely With Projector
ProjectorはJetbrainsのIDEをリモートで利用するための製品です。
自分のPCにインストールしてあるIDEをリモートから使うものではありません。
サーバーを建てて、専用クライアントまたはブラウザからアクセスして利用します。
DockerでProjector(WebStorm)を起動し、FireFoxでアクセスしたときの画面は・・・
そうだね、いつものJetbrains IDEだね!
動きについては、普通に使うのと変わりなくてよくわからない。
通信についてはRDPやX11 Forwarding、VNCと比べてほとんど無く、画面の描画に必要な部分を貰ってきて描画している様子。
強いサーバ上でうまく開発者毎に環境を提供できるようにすれば、良いリモート開発環境を作ることができそう。
ただ、デフォルトのフォントで表示する日本語が何とも言えない感じ。
この記事では、そんな何とも言えない日本語表示をいい感じにするため、JetBrains/projector-serverに手を加え、デフォルト以外のフォント(例としてCica)を埋め込む方法を示します。
注意点
- この記事を書いた時点(2021年3月23日)では日本語入力には対応していません
- Issueは既にあります(PRJ-330: Support for IME )
- "ubuntu font family"と"JetBrains Mono"が組み込まれているので、日本語フォントを埋め込まずとも日本語は表示されます
- IDE以外は表示できない(サーバーにインストールされたFireFoxとか
手順
1. JetBrains/projector-serverをcloneする
2. projector-server/build.gradle
のtask downloadMonoFonts
の下あたりに以下のtask
を追加する(ただのdownloadMonoFonts
のコピー
task downloadCicaFonts {
def cicaFontsLink = "https://github.com/miiton/Cica/releases/download/v5.0.2/Cica_v5.0.2_with_emoji.zip"
doLast {
def requiredFonts = ["Cica-R", "Cica-RI", "Cica-B", "Cica-BI"].stream().map { "$fontsPath/${it}.ttf" }.collect()
println("Checking cica fonts: $requiredFonts")
def haveAll = requiredFonts.stream().allMatch { project.file(it).exists() }
if (haveAll) {
println("Cica fonts already exist, skipping download.")
}
else {
println("Some cica fonts are missing, downloading... If some fonts exist, they will be overwritten.")
project.file(fontsPath).mkdirs()
def url = new URL(cicaFontsLink)
def tempFile = File.createTempFile("cicaFonts", "zip")
url.withInputStream { i -> tempFile.withOutputStream { it << i } }
def originalToDest = [
"Cica-Regular" : "Cica-R",
"Cica-RegularItalic": "Cica-RI",
"Cica-Bold" : "Cica-B",
"Cica-BoldItalic" : "Cica-BI",
]
def zipFile = new ZipFile(tempFile)
originalToDest.forEach { original, dest ->
def destFile = project.file("$fontsPath/${dest}.ttf")
def srcPath = "${original}.ttf"
destFile.delete()
destFile.createNewFile()
destFile.withOutputStream { it << zipFile.getInputStream(zipFile.getEntry(srcPath)) }
}
tempFile.delete()
println("Download complete")
}
}
}
3. 同じファイルのtask downloadFonts
を修正する
task downloadFonts {
- dependsOn(downloadDefaultFonts, downloadMonoFonts)
+ dependsOn(downloadDefaultFonts, downloadMonoFonts, downloadCicaFonts)
}
4. projector-server/src/main/kotlin/org/jetbrains/projector/server/service/ProjectorFontProvider.kt
の下の方にあるMONO_BI_NAME
やMONO_BI_PATH
の下あたりに以下のコードを追加する
private const val CICA_R_NAME = "Cica-R"
private const val CICA_R_PATH = "/fonts/Cica-R.ttf"
private const val CICA_RI_NAME = "Cica-RI"
private const val CICA_RI_PATH = "/fonts/Cica-RI.ttf"
private const val CICA_B_NAME = "Cica-B"
private const val CICA_B_PATH = "/fonts/Cica-B.ttf"
private const val CICA_BI_NAME = "Cica-BI"
private const val CICA_BI_PATH = "/fonts/Cica-BI.ttf"
5. 同じファイルの上の方にあるprivate val monoBoldItalic by lazy { loadFont(MONO_BI_NAME, MONO_BI_PATH) }
の下あたりに以下のコードを追加する
private val cicaRegular by lazy { loadFont(CICA_R_NAME, CICA_R_PATH) }
private val cicaRegularItalic by lazy { loadFont(CICA_RI_NAME, CICA_RI_PATH) }
private val cicaBold by lazy { loadFont(CICA_B_NAME, CICA_B_PATH) }
private val cicaBoldItalic by lazy { loadFont(CICA_BI_NAME, CICA_BI_PATH) }
6. 同じファイルのprivate val allInstalledFonts by laze {...}
内のlistOf
を修正する
private val allInstalledFonts by lazy {
fun Font2D.toFont() = Font(getFamilyName(null), style, DEFAULT_SIZE)
listOf(
defaultRegular,
defaultRegularItalic,
defaultBold,
defaultBoldItalic,
monoRegular,
monoRegularItalic,
monoBold,
- monoBoldItalic
+ monoBoldItalic,
+ cicaRegular,
+ cicaRegularItalic,
+ cicaBold,
+ cicaBoldItalic
).map(Font2D::toFont)
}
7. 同じファイルのprivate fun isMonospacedFont(name: String): Boolean
の下あたりに以下のコードを追加する
private fun isCicaFont(name: String): Boolean {
return "cica" in name.toLowerCase()
}
8. 同じファイルのoverride fun findFont2D(name: String, style: Int, fallback: Int): Font2D
を修正する
override fun findFont2D(name: String, style: Int, fallback: Int): Font2D {
if (isMonospacedFont(name)) {
return when (style) {
Font.BOLD or Font.ITALIC -> monoBoldItalic
Font.BOLD -> monoBold
Font.ITALIC -> monoRegularItalic
else -> monoRegular
}
}
+ else if (isCicaFont(name)) {
+ return when (style) {
+ Font.BOLD or Font.ITALIC -> cicaBoldItalic
+
+ Font.BOLD -> cicaBold
+
+ Font.ITALIC -> cicaRegularItalic
+
+ else -> cicaRegular
+ }
}
else {
return when (style) {
Font.BOLD or Font.ITALIC -> defaultBoldItalic
Font.BOLD -> defaultBold
Font.ITALIC -> defaultRegularItalic
else -> defaultRegular
}
}
}
動作確認
この動作確認ではDockerを利用します。
1. JetBrains/projector-dockerを修正済みのproject-serverがあるディレクトリにcloneする
ディレクトリ階層イメージ
/
|- projector-server/ <- 最初にcloneしたprojector-server
|- projector-docker/ <- 動作確認用にcloneしたprojector-docker
2. projector-docker
に移動する
3. ./build-container.sh
を実行する
例) WebStorm 2020.3.2
./build-container.sh projector-webstorm:2020.3.2 https://download.jetbrains.com/webstorm/WebStorm-2020.3.2.tar.gz
4. ./build-container.sh
が上の階層にあるproject-server(つまり修正済みのproject-server)を参照してビルドとかしてくれるので気長に待つ
5. 起動させる
docker run -it --rm -p 8887:8887 projector-webstorm:2020.3.2
6. ブラウザからアクセスする
http://{起動させたホストIP}:8887/
7. フォントを設定してみる
※ Show only monospaced fonts
のチェックを外すのを忘れないように
やったぜ
最後に
応用すれば他のフォントも埋め込めます。
FiraCodeを試したところ、リガチャも普通に表示されました。
日本語フォントを導入すると、ブラウザアクセス後すぐの画面(下の画像の画面)の時間が少し長くなります。
それは置いといて、このProjectorのすごいところはPluginもだいたい動くところです。
例えば公式の日本語化プラグインも動きます。
フォントを埋め込む方法に至るまでにいろいろ試しました。
-
敗北:
/usr/local/share/fonts
にフォントを設置してみる -
敗北:
~/.local/share/fonts
にフォントを設置してみる -
敗北:
/projector/ide/jbr/lib/fonts/
にフォントを設置してみる - などなど・・・
単純にIDEがフォントを認識している様子はありませんでしたので、最終的にprojector-serverの方に手を加えて目的を達成しました。
あとは、projector-dockerのDockerfile自体を修正したりして自分の考える最強の開発環境を作り上げればいいと思います。
Author And Source
この問題について(Jetbrains Projectorのデフォルトフォントだと日本語表示が微妙なので別のフォントを埋め込む), 我々は、より多くの情報をここで見つけました https://qiita.com/0141KoppePan/items/279273f3fee0ad287623著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .