Пример #1
0
func TestNewRichText_EnglishRussianAndChineseLanguages(t *testing.T) {
	st := SuperTest{t}
	afmFonts := afm_fonts.Families("Helvetica")
	ttfFonts := ttf_fonts.Families("Arial", "STFangsong")
	fonts := append(afmFonts, ttfFonts...)
	rt, err := New(englishRussianChinese, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	st.Must(len(rt.pieces) == 5)
	st.Equal("Here is some Russian, ", rt.pieces[0].Text)
	st.Equal(10.0, rt.pieces[0].FontSize)
	st.Equal("Неприкосновенность", rt.pieces[1].Text)
	st.Equal(10.0, rt.pieces[1].FontSize)
	st.Equal(", and some Chinese, ", rt.pieces[2].Text)
	st.Equal(10.0, rt.pieces[2].FontSize)
	st.Equal("表明你已明确同意你的回答接受评估", rt.pieces[3].Text)
	st.Equal(10.0, rt.pieces[3].FontSize)
	st.Equal(".", rt.pieces[4].Text)
	st.Equal(10.0, rt.pieces[4].FontSize)
	st.Equal(fonts[0], rt.pieces[0].Font, "Should be tagged with Helvetica font.")
	st.Equal(fonts[1], rt.pieces[1].Font, "Should be tagged with Arial font.")
	st.Equal(fonts[0], rt.pieces[2].Font, "Should be tagged with Helvetica font.")
	st.Equal(fonts[2], rt.pieces[3].Font, "Should be tagged with STFangsong font.")
	st.Equal(fonts[0], rt.pieces[4].Font, "Should be tagged with Helvetica font.")
}
Пример #2
0
func TestRichText_IsNewLine(t *testing.T) {
	st := SuperTest{t}
	font := ttf_fonts.Families("Arial")[0]

	empty := RichText{
		Text:     "",
		Font:     font,
		FontSize: 10,
	}
	st.False(empty.IsNewLine(), "An empty string is not a newline.")

	newline := RichText{
		Text:     "\n",
		Font:     font,
		FontSize: 10,
	}
	st.True(newline.IsNewLine(), "It really is a newline.")

	nonNewline := RichText{
		Text:     "Lorem",
		Font:     font,
		FontSize: 10,
	}
	st.False(nonNewline.IsNewLine(), "This isn't a newline.")
}
Пример #3
0
func arialText(s string) *RichText {
	rt, err := New(s, ttf_fonts.Families("Arial"), 10, options.Options{})
	if err != nil {
		panic(err)
	}
	return rt
}
Пример #4
0
func TestNewRichText_EnglishAndChinese_Pass(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("Arial", "STFangsong")
	rt, err := New("abc所有测def", fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	st.Equal(3, len(rt.pieces))

	st.Equal("abc", rt.pieces[0].Text)
	st.Equal(10.0, rt.pieces[0].FontSize)
	st.Equal(colors.Black, rt.pieces[0].Color, "Color should be (default) black.")
	st.False(rt.pieces[0].Underline, "Underline should be (default) false.")
	st.False(rt.pieces[0].LineThrough, "LineThrough should be (default) false.")

	st.Equal("所有测", rt.pieces[1].Text)
	st.Equal(10.0, rt.pieces[1].FontSize)
	st.Equal(colors.Black, rt.pieces[1].Color, "Color should be (default) black.")
	st.False(rt.pieces[1].Underline, "Underline should be (default) false.")
	st.False(rt.pieces[1].LineThrough, "LineThrough should be (default) false.")

	st.Equal("def", rt.pieces[2].Text)
	st.Equal(10.0, rt.pieces[2].FontSize)
	st.Equal(colors.Black, rt.pieces[2].Color, "Color should be (default) black.")
	st.False(rt.pieces[2].Underline, "Underline should be (default) false.")
	st.False(rt.pieces[2].LineThrough, "LineThrough should be (default) false.")

	st.Equal(fonts[0], rt.pieces[0].Font, "abc should be tagged with Arial font.")
	st.Equal(fonts[1], rt.pieces[1].Font, "Chinese should be tagged with STFangsong font.")
	st.Equal(fonts[0], rt.pieces[2].Font, "def should be tagged with Arial font.")
}
Пример #5
0
func richTextMixedText() *RichText {
	rt, err := New("abc所有测def", ttf_fonts.Families("Arial", "STFangsong"), 10, options.Options{})
	if err != nil {
		panic(err)
	}
	return rt
}
Пример #6
0
func TestRichText_InsertStringAtOffsets(t *testing.T) {
	st := SuperTest{t}
	afmFonts := afm_fonts.Families("Helvetica")
	ttfFonts := ttf_fonts.Families("Arial", "STFangsong")
	fonts := append(afmFonts, ttfFonts...)
	text := "Automatic "
	text1 := "hyphenation "
	text2 := "aids word wrapping."
	rt, err := New(text, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	rt, err = rt.Add(text1, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	rt, err = rt.Add(text2, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}

	offsets := []int{4, 16, 36}
	chars := rt.Chars()
	rt0 := rt.InsertStringAtOffsets("-", offsets)
	st.Equal("Auto-matic hyphen-ation aids word wrap-ping.", rt0.String())
	st.Equal(chars+len(offsets), rt0.Chars(), "New text should be larger.")
}
Пример #7
0
func courierNewText(s string) *RichText {
	rt, err := New(s, ttf_fonts.Families("Courier New"), 10, options.Options{})
	if err != nil {
		panic(err)
	}
	return rt
}
Пример #8
0
func TestNewRichText_EnglishAndChinese_substitute(t *testing.T) {
	st := SuperTest{t}
	rt, err := New("abc所有测", ttf_fonts.Families("Arial"), 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	st.Equal("abc???", rt.String())
}
Пример #9
0
func mixedText() *RichText {
	afmFonts := afm_fonts.Families("Helvetica")
	ttfFonts := ttf_fonts.Families("Arial", "STFangsong")
	fonts := append(afmFonts, ttfFonts...)
	rt, err := New(englishRussianChinese, fonts, 10, options.Options{})
	if err != nil {
		panic(err)
	}
	return rt
}
Пример #10
0
// With Chinese font first in list, Arial is not called upon for English.
func TestNewRichText_ChineseAndEnglish_Reversed(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("STFangsong", "Arial")
	rt, err := New("所有测abc", fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	st.Must(len(rt.pieces) == 0)
	st.Equal("所有测abc", rt.Text)
	st.Equal(10.0, rt.FontSize)
	st.Equal(fonts[0], rt.Font, "Should be tagged with Arial font.")
}
Пример #11
0
func TestRichText_WrapToWidth_short(t *testing.T) {
	st := SuperTest{t}
	p, err := New("Lorem ipsum.", ttf_fonts.Families("Arial"), 10, options.Options{"nobreak": true})
	if err != nil {
		t.Fatal(err)
	}
	flags := make([]wordbreaking.Flags, p.Len())
	wordbreaking.MarkRuneAttributes(p.String(), flags)
	lines := p.WrapToWidth(100, flags, false)
	st.Must(len(lines) == 1, "Should return one line.")
	st.Equal(p.Text, lines[0].Text, "Text should match.")
	st.True(p.MatchesAttributes(lines[0]))
}
Пример #12
0
func TestRichText_MatchesAttributes(t *testing.T) {
	st := SuperTest{t}

	font := ttf_fonts.Families("Arial")[0]
	p1 := RichText{
		Text:     "Lorem",
		Font:     font,
		FontSize: 10,
	}
	p2 := p1
	st.True(p1.MatchesAttributes(&p2), "Attributes should match.")

	p2.Font = ttf_fonts.Families("Arial")[0]
	st.True(p1.MatchesAttributes(&p2), "Attributes should match.")

	p2.FontSize = 12
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")

	p2 = p1
	p2.Color = colors.Azure
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")

	p2 = p1
	p2.Underline = true
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")

	p2 = p1
	p2.LineThrough = true
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")

	p2 = p1
	p2.CharSpacing = 1
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")

	p2 = p1
	p2.WordSpacing = 1
	st.False(p1.MatchesAttributes(&p2), "Attributes should not match.")
}
Пример #13
0
// 14,930 ns go1.1.2
// 14,685 ns go1.2.1
// 10,873 ns go1.4.2
//  5,664 ns go1.7.3 mbp
func BenchmarkNewRichText(b *testing.B) {
	b.StopTimer()
	afmFonts := afm_fonts.Families("Helvetica")
	ttfFonts := ttf_fonts.Families("Arial", "STFangsong")
	fonts := append(afmFonts, ttfFonts...)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := New(englishRussianChinese, fonts, 10, options.Options{})
		if err != nil {
			b.Fatal(err)
		}
	}
}
Пример #14
0
// 75.5 ns
// 76.9 ns go1.1.1
// 70.8 ns go1.1.2
// 74.1 ns go1.2.1
// 77.8 ns go1.4.2
// 48.3 ns go1.7.3 mbp
func BenchmarkRichText_IsWhiteSpace(b *testing.B) {
	b.StopTimer()
	font := ttf_fonts.Families("Arial")[0]
	piece := &RichText{
		Text:     "  \t\n\v\f\r",
		Font:     font,
		FontSize: 10,
	}
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		piece.IsWhiteSpace()
	}
}
Пример #15
0
func TestRichText_WrapToWidth_nobreak_simple(t *testing.T) {
	st := SuperTest{t}
	rt, err := New(
		"Here is a long sentence with mostly small words.",
		ttf_fonts.Families("Arial"), 10,
		options.Options{"nobreak": true})
	if err != nil {
		t.Fatal(err)
	}
	flags := make([]wordbreaking.Flags, rt.Len())
	wordbreaking.MarkRuneAttributes(rt.String(), flags)
	rt.MarkNoBreak(flags)
	lines := rt.WrapToWidth(60, flags, false)
	st.Equal(1, len(lines), "Should return a single line.")
}
Пример #16
0
func TestRichText_TrimRightFunc_complex(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("Arial")
	t1, err := New(whiteSpaceText_complex1, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	t2, err2 := t1.Add(whiteSpaceText_complex2, fonts, 10, options.Options{})
	if err2 != nil {
		t.Fatal(err2)
	}
	st.Equal(trailingwhiteSpaceText_simple, t2.String())
	t3 := t2.TrimRightFunc(unicode.IsSpace)
	st.Equal(trailingwhiteSpaceText_simple_trimmed, t3.String())
}
Пример #17
0
func TestNewRichText_English(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("Arial")
	rt, err := New("abc", fonts, 10, options.Options{"color": colors.Green, "underline": true, "line_through": true, "nobreak": true})
	if err != nil {
		t.Fatal(err)
	}
	st.Equal("abc", rt.Text)
	st.Equal(10.0, rt.FontSize)
	st.Equal(colors.Green, rt.Color)
	st.True(rt.Underline)
	st.True(rt.LineThrough)
	st.True(rt.NoBreak)
	st.Equal(fonts[0], rt.Font, "Should be tagged with Arial font.")
}
Пример #18
0
func TestRichText_Height(t *testing.T) {
	st := SuperTest{t}
	p := new(RichText)
	st.Equal(0.0, p.Height())
	fonts := ttf_fonts.Families("Courier New", "STFangsong")
	p, err := New("abc所有测", fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	ascent0 := p.pieces[0].Ascent()
	descent0 := p.pieces[0].Descent()
	ascent1 := p.pieces[1].Ascent()
	descent1 := p.pieces[1].Descent()
	maxAscent := math.Max(ascent0, ascent1)
	minDecent := math.Min(descent0, descent1)
	expected := maxAscent + -minDecent
	st.AlmostEqual(expected, p.Height(), 0.001, "Where baselines do not match, Height should allow for the tallest Ascent and Descent.")
	st.AlmostEqual(11.6029296875, p.Height(), 0.001)
}
Пример #19
0
func TestRichText_Merge_width_chars(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("Arial")
	text := "Here is some "
	text1 := "English text."
	original, err := New(text, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	original, err = original.Add(text1, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}

	width0 := original.Width()
	chars0 := original.Chars()
	merged := original.Merge()

	st.Equal(width0, merged.Width(), "Merged text should be the same width as before.")
	st.Equal(chars0, merged.Chars(), "Merged text should have same char count as before.")
}
Пример #20
0
func TestRichText_IsWhiteSpace(t *testing.T) {
	st := SuperTest{t}
	font := ttf_fonts.Families("Arial")[0]

	empty := RichText{
		Text:     "",
		Font:     font,
		FontSize: 10,
	}
	st.False(empty.IsWhiteSpace(), "Empty string should not be considered whitespace.")

	singleWhite := RichText{
		Text:     " ",
		Font:     font,
		FontSize: 10,
	}
	st.True(singleWhite.IsWhiteSpace(), "A single space should be considered whitespace.")

	multiWhite := RichText{
		Text:     "  \t\n\v\f\r",
		Font:     font,
		FontSize: 10,
	}
	st.True(multiWhite.IsWhiteSpace(), "Multiple spaces should be considered whitespace.")

	startWhite := RichText{
		Text:     "  Lorem",
		Font:     font,
		FontSize: 10,
	}
	st.False(startWhite.IsWhiteSpace(), "A piece that only starts with spaces should not be considered whitespace.")

	nonWhite := RichText{
		Text:     "Lorem",
		Font:     font,
		FontSize: 10,
	}
	st.False(nonWhite.IsWhiteSpace(), "Piece contains no whitespace.")
}
Пример #21
0
func TestRichText_WrapToWidth_nobreak_complex(t *testing.T) {
	st := SuperTest{t}
	fonts := ttf_fonts.Families("Arial")
	var rt *RichText
	var err error
	rt, err = New("Here is a ", fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	rt, err = rt.Add("long sentence with mostly", fonts, 10, options.Options{"nobreak": true})
	if err != nil {
		t.Fatal(err)
	}
	rt, err = rt.Add(" small words.", fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	flags := make([]wordbreaking.Flags, rt.Len())
	wordbreaking.MarkRuneAttributes(rt.String(), flags)
	rt.MarkNoBreak(flags)
	lines := rt.WrapToWidth(60, flags, false)
	st.Equal(3, len(lines), "Should return 3 lines.")
}
Пример #22
0
func TestRichText_Merge(t *testing.T) {
	st := SuperTest{t}
	afmFonts := afm_fonts.Families("Helvetica")
	ttfFonts := ttf_fonts.Families("Arial", "STFangsong")
	fonts := append(afmFonts, ttfFonts...)
	text := "Here is some "
	text1 := "Russian, Неприкосновенность, "
	text2 := "and some Chinese, 表明你已明确同意你的回答接受评估."
	original, err := New(text, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	original, err = original.Add(text1, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}
	original, err = original.Add(text2, fonts, 10, options.Options{})
	if err != nil {
		t.Fatal(err)
	}

	// fmt.Println("Original pieces: ", original.Count())
	// i := 0
	// original.VisitAll(func(p *RichText) {
	// 	i++
	// 	fmt.Println(i, p.Text, len(p.Pieces))
	// })

	// Node
	//     Leaf: Here is some  0
	//     Node
	// 	       Leaf: Russian,
	//         Leaf: Неприкосновенность
	//         Leaf: ,
	//     Node
	//         Leaf: and some Chinese,
	//         Leaf: 表明你已明确同意你的回答接受评估
	//         Leaf: .

	piece0 := *original.pieces[0]
	merged := original.Merge()

	// fmt.Println("Merged pieces: ", merged.Count())
	// i = 0
	// merged.VisitAll(func(p *RichText) {
	// 	i++
	// 	fmt.Println(i, p.Text, len(p.pieces))
	// })

	// Node
	// Leaf: Here is some Russian,
	// Leaf: Неприкосновенность
	// Leaf: , and some Chinese,
	// Leaf: 表明你已明确同意你的回答接受评估
	// Leaf: .

	st.Equal(text+text1+text2, merged.String())
	st.Must(len(merged.pieces) == 5)

	st.Equal("Here is some Russian, ", merged.pieces[0].Text)
	st.Equal(10.0, merged.pieces[0].FontSize)
	st.Equal(fonts[0], merged.pieces[0].Font, "Should be tagged with Helvetica font.")

	st.Equal("Неприкосновенность", merged.pieces[1].Text)
	st.Equal(10.0, merged.pieces[1].FontSize)
	st.Equal(fonts[1], merged.pieces[1].Font, "Should be tagged with Arial font.")

	st.Equal(", and some Chinese, ", merged.pieces[2].Text)
	st.Equal(10.0, merged.pieces[2].FontSize)
	st.Equal(fonts[0], merged.pieces[2].Font, "Should be tagged with Helvetica font.")

	st.Equal("表明你已明确同意你的回答接受评估", merged.pieces[3].Text)
	st.Equal(10.0, merged.pieces[3].FontSize)
	st.Equal(fonts[2], merged.pieces[3].Font, "Should be tagged with STFangsong font.")

	st.Equal(".", merged.pieces[4].Text)
	st.Equal(10.0, merged.pieces[4].FontSize)
	st.Equal(fonts[0], merged.pieces[4].Font, "Should be tagged with Helvetica font.")

	st.Equal(piece0.Text, original.pieces[0].Text, "Original should be unchanged.")
}
Пример #23
0
func TestNewRichText_EnglishAndChinese_Fail(t *testing.T) {
	st := SuperTest{t}
	_, err := New("abc所有测", ttf_fonts.Families("Arial", ""), 10, options.Options{})
	st.False(err == nil, "New should fail with Chinese text and only Arial.")
	st.Equal("No font found for 所有测.", err.Error())
}