See this thread: Typing Japanese
You could try the Lazy Text Tool plugin:
The Lazy Text Tool can do vertical to some extent, but that is for single line. So while it would work easier than say just typing it manually, it still would be a tad difficult because it wasnât really made with multiline vertical support in mind. So you would still have to do 1 line at a time.
But if there is a demand for that, it should be possible to implement in the final version.
Unfortunately, the current tool doesnât support that well. Well, you can do it if you input the svg data into the text tool but that would be difficult.
Give me a short bit and I think I can make a simply python script that can make it work. They donât need anything like bold or etc, just set japanese font and text right?
I donât think that works (unless Iâm too stupid), from what I remember thatâs one of those things that is not supported by the current text rendering engine, but integrating a new one is quite a big task (like, too ambitious for a GSoC project, now that Google cut those down).
But hey, after many delays, the new resource system is about to enter the beta phase, and then a new big project is much more feasible. A new text tool definitely comes up regularly in discussionsâŚ
Basically yes, Japanese font but not only to type vertically but also right to left.
Okay, so let me explain how this works. You hook it up to Ten Scripts and can execute it via a shortcut.
When run, it will open up a window asking you to input font name, font size, line width and line height. These are global values for the entire thing. (It is possible to make it none global but that would be more work and I think it would be better spent on the Lazy Text Tool)
You write the text like normal, from left to right, but the output will be how you want it, vertical and right to left.
To edit, text, you have to select it with the Select Shapes Tool
Note: You want to change the Font name in this script defaultFont = 'Open Sans Extrabold' to whatever font you want to use as default (like the japanese font)
Important: This script plays around with the clipboard tricks, aka, it backs up your clipboard, then uses copy and paste for editing internally. So normally it isnât a problem, just try not to have a million record excel file in the clipboard or something while using.
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import re
import time
def openWindow():
defaultFont = 'Open Sans Extrabold'
defaultFontSize = 10.0
defaultLineWidth = 100
defaultLineHeight = 100
defaultTransform = ''
w = QDialog()
layout = QVBoxLayout(w)
fontCmb = QFontComboBox()
layout.addWidget(fontCmb)
hlayout = QHBoxLayout()
fontSize = QDoubleSpinBox()
hlayout.addWidget(QLabel("Font Size:"))
hlayout.addWidget(fontSize)
widthSize = QDoubleSpinBox()
widthSize.setMaximum(200)
hlayout.addWidget(QLabel("Line Width:"))
hlayout.addWidget(widthSize)
heightSize = QDoubleSpinBox()
heightSize.setMaximum(200)
hlayout.addWidget(QLabel("Line Height:"))
hlayout.addWidget(heightSize)
layout.addLayout(hlayout)
textBox = QPlainTextEdit()
layout.addWidget(textBox)
hlayout2 = QHBoxLayout()
button1 = QPushButton("Add Text")
button1.clicked.connect(w.accept)
hlayout2.addWidget(button1)
editContent = readSvgContent()
#print (editContent)
if editContent is not None:
match = re.compile('^.*?\<text.*?id="(vf_.*?)".*$', re.DOTALL).search(editContent)
if match:
matchData = match.group(1).split('_')
defaultLineWidth = float(matchData[1])
defaultLineHeight = float(matchData[2])
matchTransform = re.compile('^.*?\<text.*?transform="(.*?)".*$', re.DOTALL).search(editContent)
if matchTransform: defaultTransform = matchTransform.group(1)
matchFont = re.compile('^.*?\<text.*?font-family="(.*?)".*$', re.DOTALL).search(editContent)
if matchFont: defaultFont = matchFont.group(1)
matchFontSize = re.compile('^.*?\<text.*?font-size="(\d+)".*$', re.DOTALL).search(editContent)
if matchFontSize: defaultFontSize = float(matchFontSize.group(1))
editContent = editContent.replace('<tspan>','<p>')
#print (editContent)
textBox.document().setHtml(editContent)
button1.setText("Edit Text")
else:
editContent = None
button2 = QPushButton("Cancel")
button2.clicked.connect(w.reject)
hlayout2.addWidget(button2)
layout.addLayout(hlayout2)
def changeFont():
font = textBox.document().defaultFont()
font.setFamily(fontCmb.currentFont().family())
textBox.document().setDefaultFont(font)
textBox.setPlainText(textBox.toPlainText())
fontCmb.currentFontChanged.connect(changeFont)
def changeFontSize():
font = textBox.document().defaultFont()
font.setPointSizeF(fontSize.value())
textBox.document().setDefaultFont(font)
textBox.setPlainText(textBox.toPlainText())
fontSize.valueChanged.connect(changeFontSize)
fontCmb.setCurrentFont(QFont(defaultFont))
changeFont()
fontSize.setValue(defaultFontSize)
changeFontSize()
widthSize.setValue(defaultLineWidth)
heightSize.setValue(defaultLineHeight)
w.show()
if w.exec_() == 0: return
lines = textBox.toPlainText().split("\n")
fontWidth = 0
hPos = 0
pretty = "\n"
blockCount = textBox.document().blockCount()
iblock = textBox.document().begin()
output = '<text '
output += 'id="vf_'+ str(widthSize.value()) +'_'+ str(heightSize.value()) +'_'+str(time.time())+'" '
output += 'transform = "'+defaultTransform+'" '
output += 'font-family="'+fontCmb.currentFont().family()+'" '
output += 'font-size="'+str(fontSize.value())+'">' + pretty
while iblock != textBox.document().end():
blockText = list(iblock.text())
blockLineCount = iblock.layout().lineCount()
fontHeight = 0
output += '<tspan y="0">' + pretty
for i in range(blockLineCount):
line = iblock.layout().lineAt(i)
for i2 in range(line.textLength()):
glyph = line.glyphRuns(line.textStart()+i2, 1)[0]
if fontWidth == 0:
rawFont = glyph.rawFont()
fontWidth = rawFont.averageCharWidth()*2
hPos = (blockCount * fontWidth * widthSize.value()) / 100
r = glyph.boundingRect()
output += '<tspan dy="'+str( (fontHeight*heightSize.value())/100 )+'" x="'+str(hPos + (( (fontWidth-r.width()/2) * widthSize.value())/100) )+'">'+blockText[i2]+'</tspan>' + pretty
fontHeight = r.height()
iblock = iblock.next()
hPos -= (fontWidth * widthSize.value()) / 100
output += '</tspan>' + pretty
output += '</text>' + pretty
doc = Krita.instance().activeDocument()
svgWidth = str( (doc.width()/72)*doc.resolution() )
svgHeight = str( (doc.height()/72)*doc.resolution() )
svgContent = '''<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!-- Created using Krita: https://krita.org -->
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:krita="http://krita.org/namespaces/svg/krita"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
width="''' + svgWidth + '''pt"
height="''' + svgHeight + '''pt"
viewBox="0 0 ''' + svgWidth + ' ' + svgHeight + '''">
<defs/>''' + output + "</svg>"
#print( svgContent )
writeSvgContent(svgContent, doc.activeNode(), (editContent is not None) )
def writeSvgContent(svgContent, layer, editMode):
mimeOldContent=QGuiApplication.clipboard().mimeData();
mimeStoreContent=QMimeData()
for mimeType in mimeOldContent.formats():
mimeStoreContent.setData(mimeType,QByteArray(mimeOldContent.data(mimeType)))
if editMode: Krita.instance().action('edit_cut').trigger()
mimeNewContent=QMimeData()
mimeNewContent.setData('image/svg', svgContent.encode())
QGuiApplication.clipboard().setMimeData(mimeNewContent)
Krita.instance().action('edit_paste').trigger()
QGuiApplication.clipboard().setMimeData(mimeStoreContent)
return None
def readSvgContent():
returnContent = None
node = Krita.instance().activeDocument().activeNode()
if node.type() != 'vectorlayer': return None
mimeOldContent=QGuiApplication.clipboard().mimeData();
mimeStoreContent=QMimeData()
for mimeType in mimeOldContent.formats():
mimeStoreContent.setData(mimeType,QByteArray(mimeOldContent.data(mimeType)))
Krita.instance().action('edit_copy').trigger()
mimeContent=QGuiApplication.clipboard().mimeData();
for mimeType in mimeContent.formats():
if mimeType.startswith('image/svg'):
returnContent = str( QByteArray(mimeContent.data(mimeType)) , 'utf-8')
break
QGuiApplication.clipboard().setMimeData(mimeStoreContent)
return returnContent
openWindow()
Now question is, should I add it to ShapesAndLayers plugin ![]()
Well, yes and no. The current SVG system does not support SVG2 so it isnât convenient, but it is possible and pretty cleanly through utilizing the tspans y, x and dy properties. I even made them all in order so technically the current text tool can add support with little programming.
But it would definitely be nice to get a better fully functioning on canvas text tool.
Oh dear, this is a mess. I will have to try and convey this to my friend. Still thx for replying
Well, over the weekend, I can expand the Python API for Krita 5.0 which the beta should hopefully be out next week. So I can completely get rid of the clipboard workaround. Then just bundle it into the ShapesAndLayers plugin so all they would have to do is install the plugin, and set their shortcut.
Unfortunately due to the string freeze, it is too late to modify the current text tool 
Edit: Also, one thing. If they want stroke and colors, they can use layer styles. Styles can be put on an entire group layer if they want to do multiple per page.
Erm you mean putting each symbol in its own tspan? Well if âIâm doing the job of the text layout engine myself and spoon-feed itâ is what you call âpretty cleanlyâ, then yeah, okay.
And it wouldnât have to be SVG 2 btw., you can do some vertical text in inkscape, it uses the writing-mode:tb-rl; attribute that is part of SVG 1.1 from what I can tell. But yes, text in SVG 1.1 seems to have a bunch of shortcomings that makes proper text definition a pain in general.
SVG 1.1 2nd edition, sure. But is there a point to it when glyph-orientation-vertical has been dropped in SVG 2? Other than maybe backwards compatibility (though most browsers donât even support it).
And by pretty clean, I meant in the form that it can be made backwards compatible with little adjustment, to explain here is the output:
<text id="vf_100.0_60.0_1628215705.9547553" transform = "matrix(1.00000026702885 0 0 1.00000026702885 35.6765714331053 20.0200017581325)" font-family="Noto Sans SemCond Blk" font-size="10.0">
<tspan y="0">
<tspan dy="0.0" x="58.796875">S</tspan>
<tspan dy="10.8" x="58.5625">e</tspan>
<tspan dy="10.8" x="58.5625">e</tspan>
<tspan dy="10.8" x="60.765625"> </tspan>
<tspan dy="10.8" x="59.78125">f</tspan>
<tspan dy="10.8" x="58.3984375">o</tspan>
<tspan dy="10.8" x="58.234375">n</tspan>
<tspan dy="10.8" x="59.515625">t</tspan>
<tspan dy="10.8" x="60.765625"> </tspan>
<tspan dy="10.8" x="60.28125">i</tspan>
<tspan dy="10.8" x="59.1796875">s</tspan>
</tspan>
<tspan y="0">
<tspan dy="0.0" x="42.671875">n</tspan>
<tspan dy="10.8" x="42.953125">o</tspan>
<tspan dy="10.8" x="41.1953125">w</tspan>
<tspan dy="10.8" x="45.203125"> </tspan>
<tspan dy="10.8" x="42.796875">b</tspan>
<tspan dy="10.8" x="43.0">e</tspan>
<tspan dy="10.8" x="44.71875">i</tspan>
<tspan dy="10.8" x="42.671875">n</tspan>
<tspan dy="10.8" x="42.796875">g</tspan>
<tspan dy="10.8" x="45.203125"> </tspan>
<tspan dy="10.8" x="42.796875">d</tspan>
<tspan dy="10.8" x="42.8359375">o</tspan>
<tspan dy="10.8" x="42.671875">n</tspan>
<tspan dy="10.8" x="43.0">e</tspan>
</tspan>
<tspan y="0">
<tspan dy="0.0" x="27.4453125">v</tspan>
<tspan dy="10.8" x="27.4375">e</tspan>
<tspan dy="10.8" x="28.3046875">r</tspan>
<tspan dy="10.8" x="28.390625">t</tspan>
<tspan dy="10.8" x="29.15625">i</tspan>
<tspan dy="10.8" x="27.875">c</tspan>
<tspan dy="10.8" x="27.3828125">a</tspan>
<tspan dy="10.8" x="29.171875">l</tspan>
<tspan dy="10.8" x="29.171875">l</tspan>
<tspan dy="10.8" x="27.453125">y</tspan>
<tspan dy="10.8" x="29.2890625">!</tspan>
<tspan dy="10.8" x="29.640625"> </tspan>
</tspan>
</text>
So I am only handling positioning of the letters. Otherwise, the blocks/lines are still maintained, and I can still wrap them in italic/bold and etc markup without doing that for every single character with little issue. So if it were say to be implemented to the current text tool, all that would be needed is adding the position of the char in the line.
Actually, the values can be flat, I simply chose to do a bit extra calculation to get centering. But if one say plans to use say Chinese that has all pretty equal sized glyphs (as far as I am aware, I could be wrong), centering doesnât matter as much. It might not even matter for Japanese, but I added it just in case.
If you take away the centering stuff, it works exactly like the current text tool. Only difference is instead of changing the dy, you change the flat x.
Let me add something.
In Japanese text, there are many characters that are misaligned or rotated 90 degrees between horizontal and vertical writing(In Japanese, this is the equivalent of the English comma or period.)
Simply changing the position from horizontal to vertical doesnât make the notation work.
I wonder how it is in ChineseâŚ
Simply changing the position from horizontal to verticalâŚâŚ
Modern Chinese people are more accustomed to writing horizontally, unless they translate Japanese manga.
Hmm⌠are there japanese fonts that are vertical only? or do they have vertical representations in Unicode?
I not sure if there is a vertical only japanese font, but as I know a japanese font has the horizontal and vertical punctuation (and such) always available. It is the text program that dictates which one is going to be used.
An example you may test if you have japanese support on your system:
- On LibreOffice Writer go to format â Page â Page â âText directionâ Right-to-left vertical
- The font I used was: Noto Serif CJK SC
Here a Screenshot
It seems that it is hard to find a font with only vertical writing.
I myself am not capable of explaining what information is contained in Unicode (because I have no knowledge of text programming). I found a site that might be helpful in explaining the process of converting a font to vertical writing, and Iâve left a partial translation below.
https://aznote.jakou.com/fforge/a03_vert.html
ââââ" translated text
If the shape and placement of the glyphs are different for horizontal and vertical writing, it is necessary to create glyphs for vertical writing separately from those for horizontal writing.
When you draw a character in a font, you can retrieve the glyphs in the font by specifying a code such as Unicode, but you basically cannot retrieve the glyphs created for vertical writing in that way.
However, glyphs created for vertical writing cannot be retrieved in this way. To find out how to retrieve vertical glyphs, the internal process when drawing a font is as follows
<Internal process for vertical writing
-
Get the ID of the glyph in the font (for horizontal writing) from Unicode or some other source.
-
For vertical writing, search the fontâs GSUB table for the above glyph ID using the âvertâ or âvrt2â information.
-
If the glyph ID is found, retrieve it since it contains the ID of the corresponding vertical writing glyph.
-
If the glyph ID for vertical writing is found, use that glyph, otherwise use the glyph for horizontal writing.
ââââ
Itâs convenient.
In Japan, horizontal writing is also common, but for some reason, manga, novels and newspapers are standardized in vertical writing.
Okay, I was able to make a vertical only font by taking the VERT glyphs and overwriting the normal glyphs. Does it look fine?
Font can be found here:
I sent this to him and here is his feedback, it looks really good but tho for one, He is not a fan of the actual font (he uses Yu Mincho,serif) second of all the full stop ( the small circle) Needs to be on the top right of each sentence but here it has two that is on both top right and top left, finally he wishes to know if it can type kanji as well ( But I believe it can) It is also typed from right to left right?
If you look at the top chart I posted, there is one with the circle being top right. Is that not the one? (There is also one on top left?)
I donât have a japanese keyboard, so I would need at least a sentence so I can copy an paste and see which one it is that actually shows up. It being there isnât an issue as if it is typed or not.
As for Yu Mincho, I donât think that is an option. The problem isnât being not able to do it, but that font has a commercial license. If your friend uses it and isnât paying for the license, he can find himself in legal trouble (if anyone bothers). But it also means I canât redistribute a modified version. You need an open source font under an open source license like SIL OFL
Yes, the font has some kanji. You can google the font as I kept the same name just added Vertical. Description said it goes up to 2nd grade kanji.
I checked the sample image and thought it was very good.
I tried to check the font, but due to a problem on my end, the KDE authentication didnât work and I couldnât check it.
Iâm sorry, but can you upload it to another place like github?




