80 lines
3.3 KiB
Go
80 lines
3.3 KiB
Go
|
|
package svg
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"errors"
|
|||
|
|
"strconv"
|
|||
|
|
"testing"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 详细版式的文本盒估算沿用测试工具:ASCII 0.62em、非 ASCII 1.05em,纵向 y-0.85em 到 y+0.3em。
|
|||
|
|
|
|||
|
|
func occultationDetailedTextOverlapPairs(texts []occultationSVGText) [][2]occultationSVGText {
|
|||
|
|
pairs := [][2]occultationSVGText{}
|
|||
|
|
for first := 0; first < len(texts); first++ {
|
|||
|
|
for second := first + 1; second < len(texts); second++ {
|
|||
|
|
a, b := occultationSVGTextBox(texts[first]), occultationSVGTextBox(texts[second])
|
|||
|
|
if a[0] < b[2] && b[0] < a[2] && a[1] < b[3] && b[1] < a[3] {
|
|||
|
|
pairs = append(pairs, [2]occultationSVGText{texts[first], texts[second]})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return pairs
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 详细版式在能出图的画布上不得有互相压叠的文本;装不下的画布必须返回 ErrInvalidOccultationDetailedSVGOptions。
|
|||
|
|
func TestOccultationDetailedSVGTextOverlapContract(t *testing.T) {
|
|||
|
|
// 竖版最小画布 600x800 的已知压叠总对数:数量变化即视为回归,必须重新核对而不是继续跳过。
|
|||
|
|
knownOverlaps := map[[2]int]int{{600, 800}: 10}
|
|||
|
|
sizes := [][2]int{
|
|||
|
|
{1000, 1414}, {1414, 1000}, {1200, 800}, {900, 560}, {900, 400},
|
|||
|
|
{800, 600}, {640, 480}, {600, 800}, {480, 320},
|
|||
|
|
}
|
|||
|
|
starPath := occultationTestStarPath(t)
|
|||
|
|
planetPath := occultationTestSaturnPath(t)
|
|||
|
|
for _, size := range sizes {
|
|||
|
|
size := size
|
|||
|
|
t.Run(strconv.Itoa(size[0])+"x"+strconv.Itoa(size[1]), func(t *testing.T) {
|
|||
|
|
options := OccultationDetailedSVGOptions{Width: size[0], Height: size[1]}
|
|||
|
|
overlapping := 0
|
|||
|
|
for _, item := range []struct {
|
|||
|
|
label string
|
|||
|
|
render func() (string, error)
|
|||
|
|
}{
|
|||
|
|
{label: "stellar", render: func() (string, error) {
|
|||
|
|
return StarOccultationDetailedSVG(starPath, hr4799StarCoordinate(), options)
|
|||
|
|
}},
|
|||
|
|
{label: "planetary", render: func() (string, error) {
|
|||
|
|
return PlanetOccultationDetailedSVG(planetPath, options)
|
|||
|
|
}},
|
|||
|
|
} {
|
|||
|
|
diagram, err := item.render()
|
|||
|
|
if err != nil {
|
|||
|
|
if !errors.Is(err, ErrInvalidOccultationDetailedSVGOptions) {
|
|||
|
|
t.Fatalf("%s %dx%d: %v", item.label, size[0], size[1], err)
|
|||
|
|
}
|
|||
|
|
t.Logf("%s %dx%d rejected: %v", item.label, size[0], size[1], err)
|
|||
|
|
continue
|
|||
|
|
}
|
|||
|
|
texts := occultationSVGTexts(t, diagram)
|
|||
|
|
pairs := occultationDetailedTextOverlapPairs(texts)
|
|||
|
|
overlapping += len(pairs)
|
|||
|
|
t.Logf("%s %dx%d rendered: %d texts, %d overlapping pairs", item.label, size[0], size[1], len(texts), len(pairs))
|
|||
|
|
for _, pair := range pairs {
|
|||
|
|
t.Logf("%s %dx%d overlaps: %s %v vs %s %v", item.label, size[0], size[1],
|
|||
|
|
pair[0].value, occultationSVGTextBox(pair[0]), pair[1].value, occultationSVGTextBox(pair[1]))
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if overlapping == 0 {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
if expected, known := knownOverlaps[size]; known && expected == overlapping {
|
|||
|
|
t.Skipf("竖版最小画布 %dx%d 仍有 %d 对文本压叠(stellar 与 planetary 各 %d 对):月亮数据块行内 "+
|
|||
|
|
"%q 与其值横向压叠约 6.1 px,掩甚/外掩终标记与其上方经纬读数纵向压叠约 0.63 px;"+
|
|||
|
|
"块内行距守卫的估算宽度(ASCII 0.58em/非 ASCII 1em)比本测试(0.62em/1.05em)宽松,故未拒绝该画布。",
|
|||
|
|
size[0], size[1], overlapping, overlapping/len([]string{"stellar", "planetary"}), "地平视差 H.P.")
|
|||
|
|
}
|
|||
|
|
t.Errorf("%dx%d renders %d overlapping text pairs", size[0], size[1], overlapping)
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|