まだ問題はあるけど、できた!
「う」と「え」がくっつきすぎ
これは期待通り
前回は文字が収まるピッタリの四角形(緑枠)を元にしていたので
字間指定が0だと
緑枠が隣り合う(間隔が0)こうなっていた
四角形で判定しているからこれ以上近づけないし
もしマイナスの値を指定したらWとAは良くなるけど
Vの右上とWの左上が交差してしまうことになる
文字間0で期待するAの描画位置はこの状態の時Wの描画位置を(0,0)のとき
Aの描画位置(x,0)のxが知りたい
Aの一つ前の文字Wの右端と同じ高さにある今から描画する文字Aの左空間と
Wの左端からの左空間を合計したもの(上がわの緑の横線の長さ)と
今から描画する文字Aの左端と同じ高さにある一個前の文字Wの右空間と
Aの左端からの左空間を合計したもの(下側の緑の横線の長さ)を
比較して短い方の距離分を使えば良さそうと思いついて
こうなって
上が29で下が26、だから26を使う
Wの描画範囲(緑枠)の隣にAがあった時に
Aの描画位置をそこから左に26移動させればちょど良くなるはず
こうなるから合っている
26はだいたいわかったからあとはWのとなりになるようなAの座標
これはWの緑枠の右上の座標だから
Wの左空間は9だから文字間0指定なら左に9だから0-9で-9
Wの描画範囲(緑枠)の幅は56だから右上のx座標は
56-9=47
(47,0)にAを描画したところ
ここから47からさっきの26引いて
47-26=21
これがAの描画位置
(21,0)にAを描画したところ、あっている
字間指定10で描画したところ
前回よりは良くなったけど
ターンを字間指定0で描画
「タ」と「ー」がどう見ても離れすぎている
「ー」と「ン」は良さそうに見えて実際いいんだけど
予想ではもっと近づくはずだった
ターンをそれぞれ1文字ごとに普通に描画した場合の描画範囲
今回の方法で描画するとき使う数字
本当は0のところが「ー」の幅いっぱいの48になるように作ったつもりだったけど
0になっているみたい
だからタとーの場合だと9と11+10=21を比較して小さい方の9が選択されている
期待したのは9+48=57と11+10=21を比較して小さい方の21だった
でもこれは0だったら文字の幅を返せばいいからすぐ解決できるとして
でもそうすると
「ー」と「ン」の場合
今回は0+9=9と10+30=40で9を使っていたのが
48+9=57と10+30=40の比較になって40を使うことになる
そうするとたぶんこうなる
で、解決方法が思いつかない
Public Structure DrawRange2描画範囲
Public Property AllSize As Size
Public Property TopX As List(Of Integer)
Public Property TopY As Integer
Public Property BottomX As List(Of Integer)
Public Property BottomY As Integer
Public Property LeftX As Integer
Public Property LeftY As List(Of Integer)
Public Property RightX As Integer
Public Property RightY As List(Of Integer)
Public Overrides Function ToString() As String
Dim str As String
str = "TopY=" & TopY & " BottomY=" & BottomY & " LeftX=" & LeftX & " RightX=" & RightX &
" TopX_Count=" & TopX.Count & " BottomX_Count=" & BottomX.Count & " LeftY_Count=" & LeftY.Count & " RightY_Count=" & RightY.Count
Return str
End Function
Public Function myString1() As String
Dim str As String = "TopY=" & TopY & " BottomY=" & BottomY & " LeftX=" & LeftX & " RightX=" & RightX & " Width=" & RightX - LeftX + 1 & " Height=" & BottomY - TopY + 1
Return str
End Function
Public Function myString2() As String
Return " TopX_Count=" & TopX.Count & " BottomX_Count=" & BottomX.Count & " LeftY_Count=" & LeftY.Count & " RightY_Count=" & RightY.Count
End Function
Public Function DrawWidth() As Integer
Return RightX - LeftX + 1
End Function
Public Function DrawHeight() As Integer
Return BottomY - TopY + 1
End Function
Public Function DrawSize() As Size
Return New Size(DrawWidth, DrawHeight)
End Function
Public Function RightSpace() As Integer
Return Me.AllSize.Width - RightX - 1
End Function
End Structure
描画範囲の情報とか入れておく構造体のDrawRange2描画範囲
前回に付け足したのが文字描画全体のサイズ範囲を入れておくSize型のAllSizeと
だけかな、ほとんど同じ
Public Structure QuartetSpace上下左右の空白
Dim Top As Integer
Dim Bottom, Left, Right As Integer
End Structure
数値を入れておくだけならPropertyじゃなくてDimでもいいみたい
しかも「,」で区切ってまとめて宣言してもいいみたい
間違っているかもしれないけど期待通りに動いている
これを使っているのは
11や7はDrawRange2描画範囲に入っている数字からすぐわかるけど
18と19は別の関数(LeftSpace指定座標の距離一覧)で探すことになるのでそれ用
TopとBottomは縦書の時に必要になりそう
↓が18とか19の場所を探す関数
Private Function LeftSpace指定座標の距離一覧(bmp As Bitmap, dr As DrawRange2描画範囲) As QuartetSpace上下左右の空白
Dim reInte As QuartetSpace上下左右の空白
Dim w As Integer = bmp.Width
Dim h As Integer = bmp.Height
Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim bmpData As BitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat)
Dim ptr As IntPtr = bmpData.Scan0
Dim data As Integer = bmpData.Stride * h - 1
Dim pixels(data) As Byte
Runtime.InteropServices.Marshal.Copy(ptr, pixels, 0, pixels.Length)
Dim pos As Integer = 0
Dim x, y As Integer
Dim isFind As Boolean = False
For x = 0 To w - 1
For y = dr.RightY(0) To dr.RightY(dr.RightY.Count - 1)
pos = y * bmpData.Stride + x * 4
If pixels(pos + 3) <> 0 Then
If isFind = False Then
isFind = True
reInte.Left = x
Exit For
End If
End If
Next
If isFind Then Exit For
Next
isFind = False
For x = w - 1 To 0 Step -1
For y = dr.LeftY(0) To dr.LeftY(dr.LeftY.Count - 1)
pos = y * bmpData.Stride + x * 4
If pixels(pos + 3) <> 0 Then
If isFind = False Then
isFind = True
reInte.Right = w - x - 1
Exit For
End If
End If
Next
If isFind Then Exit For
Next
bmp.UnlockBits(bmpData)
Return reInte
End Function
画像を渡して指定された座標の範囲の中から一番先に見つかった色付きの
横書きしか使っていないので左右しか使っていない
これは前回に書いた関数のDrawRange2描画範囲情報のコピペ改変
これ以上書いて投稿するとエラーになるから分割になった
続きは