From a9b8dcba7d452faaee584deab37b9ea611805ac0 Mon Sep 17 00:00:00 2001 From: nulano Date: Thu, 23 Apr 2020 05:38:41 +0200 Subject: [PATCH] write anchor docs (cherry picked from commit dcaee36941e6cb5e6f93186b6f819fb74887e0d3) --- docs/example/anchors.png | Bin 0 -> 12593 bytes docs/example/anchors.py | 29 + docs/handbook/appendices.rst | 1 + docs/handbook/text-anchors.rst | 140 +++++ docs/reference/ImageDraw.rst | 63 +- docs/resources/anchor_horizontal.svg | 467 +++++++++++++++ docs/resources/anchor_vertical.svg | 841 +++++++++++++++++++++++++++ src/PIL/ImageFont.py | 4 +- 8 files changed, 1484 insertions(+), 61 deletions(-) create mode 100644 docs/example/anchors.png create mode 100644 docs/example/anchors.py create mode 100644 docs/handbook/text-anchors.rst create mode 100644 docs/resources/anchor_horizontal.svg create mode 100644 docs/resources/anchor_vertical.svg diff --git a/docs/example/anchors.png b/docs/example/anchors.png new file mode 100644 index 0000000000000000000000000000000000000000..17585a4129591f6439aad82918456e179e0b7f97 GIT binary patch literal 12593 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 -for more information on the specific terms used. - - Example: Draw Partial Opacity Text ---------------------------------- @@ -358,8 +303,8 @@ Methods :param font: An :py:class:`~PIL.ImageFont.ImageFont` instance. :param anchor: The text anchor alignment. Determines the relative location of the anchor to the text. The default alignment is top left. - See :ref:`Text anchors` for valid values. This parameter is - ignored for legacy PIL fonts. + See :ref:`text-anchors` for valid values. This parameter is + ignored for non-TrueType fonts. .. note:: This parameter was present in earlier versions of Pillow, but implemented only in version 7.2.0. @@ -418,8 +363,8 @@ Methods :param anchor: The text anchor alignment. Determines the relative location of the anchor to the text. The default alignment is top left. - See :ref:`Text anchors` for valid values. This parameter is - ignored for legacy PIL fonts. + See :ref:`text-anchors` for valid values. This parameter is + ignored for non-TrueType fonts. .. note:: This parameter was present in earlier versions of Pillow, but implemented only in version 7.2.0. diff --git a/docs/resources/anchor_horizontal.svg b/docs/resources/anchor_horizontal.svg new file mode 100644 index 000000000..a0648a10c --- /dev/null +++ b/docs/resources/anchor_horizontal.svg @@ -0,0 +1,467 @@ + + + + + Pillow horizontal text anchors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Pillow horizontal text anchors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (d) descender + (s) baseline + (a) ascender + (m) middle + (t) top + (b) bottom + (l) left + (r) right + (m) middle + + + Horizontal text + + diff --git a/docs/resources/anchor_vertical.svg b/docs/resources/anchor_vertical.svg new file mode 100644 index 000000000..95da30ffd --- /dev/null +++ b/docs/resources/anchor_vertical.svg @@ -0,0 +1,841 @@ + + + + + Pillow vertical text anchors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Pillow vertical text anchors + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (l)left + (s) baseline + (r)right + (t) top + (m) middle + (b) bottom + (m)middle + (l)left + (s) baseline + (r)right + (t) top + (m) middle + (b) bottom + (m)middle + + + Verticaltext + + diff --git a/src/PIL/ImageFont.py b/src/PIL/ImageFont.py index 75ff485da..1fe19ac52 100644 --- a/src/PIL/ImageFont.py +++ b/src/PIL/ImageFont.py @@ -398,7 +398,7 @@ class FreeTypeFont: :param anchor: The text anchor alignment. Determines the relative location of the anchor to the text. The default alignment is top left. - See :ref:`Text anchors` for valid values. + See :ref:`text-anchors` for valid values. .. versionadded:: 8.0.0 @@ -477,7 +477,7 @@ class FreeTypeFont: :param anchor: The text anchor alignment. Determines the relative location of the anchor to the text. The default alignment is top left. - See :ref:`Text anchors` for valid values. + See :ref:`text-anchors` for valid values. .. versionadded:: 8.0.0