mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
// Copyright 2025-2026 肖其顿 (XIAO QI DUN)
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package ofdgo
|
|
|
|
import "slices"
|
|
|
|
// TextPositioner 按OFD坐标及增量定位连续字形,不依赖字体或绘图库
|
|
type TextPositioner struct {
|
|
xs, ys, dxs, dys []float64
|
|
current Point
|
|
index int
|
|
}
|
|
|
|
// textCodeOrigins 按标准继承文本段原点,首段缺失坐标时以零横坐标和字体上升高度容错恢复
|
|
// 入参: codes 文本段, ascent 对象坐标系下的字体上升高度
|
|
// 返回: []TextCode 定位文本段,不修改原始数据
|
|
func textCodeOrigins(codes []TextCode, ascent float64) []TextCode {
|
|
for i, code := range codes {
|
|
if code.X != "" && code.Y != "" {
|
|
continue
|
|
}
|
|
result := slices.Clone(codes)
|
|
var x, y string
|
|
if i > 0 {
|
|
x, y = codes[i-1].X, codes[i-1].Y
|
|
} else {
|
|
x, y = "0", ofdNumber(ascent)
|
|
}
|
|
for j := i; j < len(result); j++ {
|
|
if result[j].X == "" {
|
|
result[j].X = x
|
|
}
|
|
if result[j].Y == "" {
|
|
result[j].Y = y
|
|
}
|
|
x, y = result[j].X, result[j].Y
|
|
}
|
|
return result
|
|
}
|
|
return codes
|
|
}
|
|
|
|
// NewTextPositioner 创建单个TextCode的定位器,缺省位移不改变字形原点
|
|
// 入参: code 文本定位数据
|
|
// 返回: TextPositioner 字形定位器
|
|
func NewTextPositioner(code TextCode) TextPositioner {
|
|
return TextPositioner{xs: parseFloats(code.X), ys: parseFloats(code.Y), dxs: parseFloats(code.DeltaX), dys: parseFloats(code.DeltaY)}
|
|
}
|
|
|
|
// Next 根据坐标与位移返回下一个字形原点
|
|
// 返回: Point 字形原点
|
|
func (p *TextPositioner) Next() Point {
|
|
i := p.index
|
|
if i < len(p.xs) {
|
|
p.current.X = p.xs[i]
|
|
} else if i > 0 {
|
|
if dx, ok := textDelta(p.dxs, i-1); ok {
|
|
p.current.X += dx
|
|
}
|
|
}
|
|
if i < len(p.ys) {
|
|
p.current.Y = p.ys[i]
|
|
} else if i > 0 {
|
|
if dy, ok := textDelta(p.dys, i-1); ok {
|
|
p.current.Y += dy
|
|
}
|
|
}
|
|
p.index++
|
|
return p.current
|
|
}
|