Skip to content
31 changes: 31 additions & 0 deletions src/skia/Paragraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void initParagraph(py::module &m) {
py::class_<FontCollection, sk_sp<FontCollection>, SkRefCnt> font_collection(m, "textlayout_FontCollection");
py::class_<ParagraphBuilder> paragraph_builder(m, "textlayout_ParagraphBuilder");
py::class_<ParagraphStyle> paragraph_style(m, "textlayout_ParagraphStyle");
py::class_<StrutStyle> strut_style(m, "textlayout_StrutStyle");
py::class_<TextStyle> text_style(m, "textlayout_TextStyle");
py::class_<Paragraph> paragraph(m, "textlayout_Paragraph");

Expand Down Expand Up @@ -82,6 +83,20 @@ paragraph_builder
.def("Build", &ParagraphBuilder::Build)
;

strut_style
.def(py::init())
.def("setStrutEnabled",
py::overload_cast<const bool>(&StrutStyle::setStrutEnabled),
R"docstring(
)docstring",
py::arg("strutenabled"))
.def("setLeading",
py::overload_cast<const SkScalar>(&StrutStyle::setLeading),
R"docstring(
)docstring",
py::arg("leading"))
;

paragraph_style
.def(py::init())
.def("setTextStyle",
Expand All @@ -94,6 +109,11 @@ paragraph_style
R"docstring(
)docstring",
py::arg("align"))
.def("setStrutStyle",
py::overload_cast<StrutStyle>(&ParagraphStyle::setStrutStyle),
R"docstring(
)docstring",
py::arg("strutstyle"))
;

font_collection
Expand Down Expand Up @@ -154,6 +174,16 @@ text_style
R"docstring(
)docstring",
py::arg("locale"))
.def("setLetterSpacing",
py::overload_cast<SkScalar>(&TextStyle::setLetterSpacing),
R"docstring(
)docstring",
py::arg("letterspacing"))
.def("setWordSpacing",
py::overload_cast<SkScalar>(&TextStyle::setWordSpacing),
R"docstring(
)docstring",
py::arg("wordspacing"))
.def("setDecoration",
py::overload_cast<TextDecoration>(&TextStyle::setDecoration),
R"docstring(
Expand Down Expand Up @@ -208,6 +238,7 @@ m.attr("textlayout").attr("FontCollection") = m.attr("textlayout_FontCollection"
m.attr("textlayout").attr("ParagraphBuilder") = m.attr("textlayout_ParagraphBuilder");
m.attr("textlayout").attr("ParagraphStyle") = m.attr("textlayout_ParagraphStyle");
m.attr("textlayout").attr("Paragraph") = m.attr("textlayout_Paragraph");
m.attr("textlayout").attr("StrutStyle") = m.attr("textlayout_StrutStyle");
m.attr("textlayout").attr("TextStyle") = m.attr("textlayout_TextStyle");
m.attr("textlayout").attr("TextAlign") = m.attr("textlayout_TextAlign");
m.attr("textlayout").attr("TextDecoration") = m.attr("textlayout_TextDecoration");
Expand Down
4 changes: 4 additions & 0 deletions src/skia/TextBlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ py::class_<SkTextBlob::Iter::Run>(iter, "Run")

iter
.def(py::init<const SkTextBlob&>())
.def("__iter__",
[] (SkTextBlob::Iter& it) {
return it;
})
.def("__next__",
[] (SkTextBlob::Iter& it) {
SkTextBlob::Iter::Run run;
Expand Down
114 changes: 114 additions & 0 deletions tests/test_paragraph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import skia
import pytest
import operator

@pytest.fixture(scope='session')
def textlayout_font_collection():
Expand All @@ -17,6 +18,14 @@ def test_ParagraphStyle_init0(paragraph_style):
assert isinstance(paragraph_style, skia.textlayout_ParagraphStyle)


@pytest.fixture(scope='session')
def strut_style():
return skia.textlayout.StrutStyle()

def test_StrutStyle_init0(strut_style):
assert isinstance(strut_style, skia.textlayout_StrutStyle)


@pytest.fixture(scope='session')
def textlayout_text_style():
return skia.textlayout.TextStyle()
Expand Down Expand Up @@ -61,3 +70,108 @@ def test_Paragraph_linebreak(paragraph_builder, textlayout_text_style, textlayou
paragraph = builder.Build()
paragraph.layout(300)
assert (paragraph.Height > 0) and (paragraph.Height > paragraph.LongestLine * 2)


Comment thread
stenson marked this conversation as resolved.
@pytest.mark.parametrize('test_operator, spec_a, spec_b', [
(operator.eq, (False, 1.0), (True, 1.0)),
(operator.eq, (True, 0), (True, 1.0)),
(operator.eq, (True, 0.5), (True, 1.0)),
(operator.lt, (True, 1.0), (True, 2.0)),
(operator.lt, (True, 2.0), (True, 3.0)),
])
def test_Paragraph_strutHeight(paragraph_builder, textlayout_text_style, textlayout_font_collection, paragraph_style, test_operator, strut_style, spec_a, spec_b):
paint = skia.Paint()
paint.setColor(skia.ColorBLACK)
paint.setAntiAlias(True)

textlayout_text_style.setFontSize(50)
textlayout_text_style.setForegroundPaint(paint)

textlayout_font_collection.setDefaultFontManager(skia.FontMgr())

def graf_with_strut(enabled, leading_factor):
strut_style.setStrutEnabled(enabled)
strut_style.setLeading(leading_factor)
paragraph_style.setStrutStyle(strut_style)

builder = skia.textlayout.ParagraphBuilder.make(
paragraph_style, textlayout_font_collection, skia.Unicodes.ICU.Make()
)
builder.pushStyle(textlayout_text_style)

builder.addText("o\no")
paragraph = builder.Build()
paragraph.layout(300)

return paragraph

paragraph_a_height = graf_with_strut(*spec_a).Height
paragraph_b_height = graf_with_strut(*spec_b).Height

assert test_operator(paragraph_a_height, paragraph_b_height)


@pytest.mark.parametrize('spacing_a, spacing_b', [
(-1, 0),
(0, 1),
(1, 2),
(2, 3),
(-1, 1),
])
def test_Paragraph_letterSpacing(paragraph_builder, textlayout_text_style, textlayout_font_collection, paragraph_style, strut_style, spacing_a, spacing_b):
paint = skia.Paint()
paint.setColor(skia.ColorBLACK)
paint.setAntiAlias(True)

textlayout_font_collection.setDefaultFontManager(skia.FontMgr())

def graf_with_letterspacing(letterspacing):
textlayout_text_style.setFontSize(50)
textlayout_text_style.setForegroundPaint(paint)
textlayout_text_style.setLetterSpacing(letterspacing)

builder = skia.textlayout.ParagraphBuilder.make(
paragraph_style, textlayout_font_collection, skia.Unicodes.ICU.Make()
)
builder.pushStyle(textlayout_text_style)

builder.addText("ooo")
paragraph = builder.Build()
paragraph.layout(300)

return paragraph

assert graf_with_letterspacing(spacing_a).LongestLine < graf_with_letterspacing(spacing_b).LongestLine


@pytest.mark.parametrize('spacing_a, spacing_b', [
(-1, 0),
(0, 1),
(1, 2),
(2, 3),
(-1, 1),
])
def test_Paragraph_wordSpacing(paragraph_builder, textlayout_text_style, textlayout_font_collection, paragraph_style, strut_style, spacing_a, spacing_b):
paint = skia.Paint()
paint.setColor(skia.ColorBLACK)
paint.setAntiAlias(True)

textlayout_font_collection.setDefaultFontManager(skia.FontMgr())

def graf_with_word_spacing(letterspacing):
textlayout_text_style.setFontSize(50)
textlayout_text_style.setForegroundPaint(paint)
textlayout_text_style.setWordSpacing(letterspacing)

builder = skia.textlayout.ParagraphBuilder.make(
paragraph_style, textlayout_font_collection, skia.Unicodes.ICU.Make()
)
builder.pushStyle(textlayout_text_style)

builder.addText("word word word")
paragraph = builder.Build()
paragraph.layout(300)

return paragraph

assert graf_with_word_spacing(spacing_a).LongestLine < graf_with_word_spacing(spacing_b).LongestLine