in arm64/arm64spec/spec.go [428:617]
func readBitBox(name string, content pdf.Content, text []pdf.Text, i int) (string, int) {
// Bits headings
y3 := 0.0
x1 := 0.0
for i < len(text) && match(text[i], "Arial", 8, "") {
if y3 == 0 {
y3 = text[i].Y
}
if x1 == 0 {
x1 = text[i].X
}
if text[i].Y != y3 {
break
}
i++
}
// Bits fields in box
x2 := 0.0
y2 := 0.0
dy1 := 0.0
for i < len(text) && match(text[i], "Arial", 8, "") {
if x2 < text[i].X+text[i].W {
x2 = text[i].X + text[i].W
}
if y2 == 0 {
y2 = text[i].Y
}
if text[i].Y != y2 {
break
}
dy1 = text[i].FontSize
i++
}
// Bits fields below box
x3 := 0.0
y1 := 0.0
for i < len(text) && match(text[i], "Arial", 8, "") {
if x3 < text[i].X+text[i].W {
x3 = text[i].X + text[i].W
}
y1 = text[i].Y
if text[i].Y != y1 {
break
}
i++
}
//no bits fields below box
below_flag := true
if y1 == 0.0 {
below_flag = false
y1 = y2
}
// Encoding box
if debugPage > 0 {
fmt.Println("encoding box", x1, y3, x2, y1)
}
// Find lines (thin rectangles) separating bit fields.
var bottom, top pdf.Rect
const (
yMargin = 0.25 * 72
xMargin = 2 * 72
)
cont := 0
if below_flag == true {
for _, r := range content.Rect {
cont = cont + 1
if x1-xMargin < r.Min.X && r.Min.X < x1 && x2 < r.Max.X && r.Max.X < x2+xMargin {
if y1-yMargin < r.Min.Y && r.Min.Y < y2-dy1 {
bottom = r
}
if y2+dy1 < r.Min.Y && r.Min.Y < y3+yMargin {
top = r
}
}
}
} else {
for _, r := range content.Rect {
cont = cont + 1
if x1-xMargin < r.Min.X && r.Min.X < x1 && x2 < r.Max.X && r.Max.X < x2+xMargin {
if y1-yMargin-dy1 < r.Min.Y && r.Min.Y < y3-dy1 {
bottom = r
}
if y2+dy1 < r.Min.Y && r.Min.Y < y3+yMargin {
top = r
}
}
}
}
if debugPage > 0 {
fmt.Println("top", top, "bottom", bottom, "content.Rect number", cont)
}
const ε = 0.5 * 72
cont_1 := 0
var bars []pdf.Rect
for _, r := range content.Rect {
if math.Abs(r.Min.X-r.Max.X) < bottom.Max.X-bottom.Min.X-(ε/2) && math.Abs(r.Min.Y-bottom.Min.Y) < ε && math.Abs(r.Max.Y-top.Min.Y) < ε {
cont_1 = cont_1 + 1
bars = append(bars, r)
}
}
sort.Sort(RectHorizontal(bars))
if debugPage > 0 {
fmt.Println("==bars number==", cont_1)
}
// There are 16-bit and 32-bit encodings.
// In practice, they are about 2.65 and 5.3 inches wide, respectively.
// Use 4 inches as a cutoff.
nbit := 32
dx := top.Max.X - top.Min.X
if top.Max.X-top.Min.X < 4*72 {
nbit = 16
}
total := 0
var buf bytes.Buffer
for i := 0; i < len(bars); i++ {
if i > 0 {
fmt.Fprintf(&buf, "|")
}
var sub []pdf.Text
x1, x2 := bars[i].Min.X, bars[i].Max.X
for _, t := range content.Text {
tx := t.X + t.W/2
ty := t.Y
if x1 < tx && tx < x2 && y2-dy1 < ty && ty < y2+dy1 {
sub = append(sub, t)
}
}
var str []string
for _, t := range findWords(sub) {
str = append(str, t.S)
}
s := strings.Join(str, " ")
s = strings.Replace(s, ")(", ") (", -1)
// If bits contain "!" or "x", be replaced by the bits below it.
if strings.Contains(s, "!") || strings.Contains(s, "x") {
var sub1 []pdf.Text
for _, t := range content.Text {
tx := t.X + t.W/2
ty := t.Y
if x1 < tx && tx < x2 && y1-dy1 < ty && ty < y1+dy1 {
sub1 = append(sub1, t)
}
}
var str1 []string
for _, t := range findWords(sub1) {
str1 = append(str1, t.S)
}
s = strings.Join(str1, " ")
s = strings.Replace(s, ")(", ") (", -1)
}
n := len(strings.Fields(s))
var b int
if IMMRE.MatchString(s) {
bitNum := strings.TrimPrefix(s, "imm")
b, _ = strconv.Atoi(bitNum)
} else if s == "immhi" {
b = 19
} else {
b = int(float64(nbit)*(x2-x1)/dx + 0.5)
}
if n == b {
for k, f := range strings.Fields(s) {
if k > 0 {
fmt.Fprintf(&buf, "|")
}
fmt.Fprintf(&buf, "%s", f)
}
} else {
if n != 1 {
fmt.Fprintf(os.Stderr, "%s - multi-field %d-bit encoding: %s\n", name, n, s)
}
fmt.Fprintf(&buf, "%s:%d", s, b)
}
total += b
}
if total != nbit || total == 0 {
fmt.Fprintf(os.Stderr, "%s - %d-bit encoding\n", name, total)
}
return buf.String(), i
}