Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Arcade [PyPi Release History](https://pypi.org/project/arcade/#history) page.
- Sped up `arcade.draw_text()`. It no longer flushes OpenGL after every call (an unchanged call went from 76 to 15 µs), and several lines drawn in the same style each keep their own cached label instead of re-laying out one label every call (5 static lines went from 1.24 ms to 0.08 ms per frame). Any number of lines can share a style. A line whose text changes reuses its own label from the previous frame, found by the clock's tick count, instead of making a new one.
- Sped up `arcade.Text` updates. Setting a property to the value it already has no longer lays out the text again (for example `font_size`, `bold`, or `width` went from about 165 µs to under 1 µs), and a `with text:` block only lays out the text if something in it needs a new layout. An unchanged `arcade.TextPool` frame with 5 lines went from 760 µs to 6 µs.
- Added a "Drawing Text" page to the programming guide: choosing between `draw_text`, `Text`, `TextPool`, and `create_text_sprite`, what's slow and fast to change, batches, fonts (names, font files, and the bundled Kenney and Liberation fonts), and styles. Updated the text section of the performance tips, and the `draw_text` warning and docstring, which overstated how slow it is.
- Tile maps no longer use Pillow's `Image.getdata()`, which is deprecated and will be removed in Pillow 14, to apply an image layer's transparent color. It's done with Pillow operations instead, which is also faster (a 1024x600 image went from 76 ms to 4 ms).

## 4.0.0.dev8

Expand Down
35 changes: 19 additions & 16 deletions arcade/tilemap/tilemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import math
import os
from collections import OrderedDict
from collections.abc import Callable, Sequence
from collections.abc import Callable
from pathlib import Path
from typing import TYPE_CHECKING, Any, cast

import PIL.Image
import PIL.ImageChops
import pytiled_parser
import pytiled_parser.tiled_object
from pytiled_parser import Color
Expand All @@ -32,7 +34,6 @@
hexagon,
)
from arcade.hitbox import HitBoxAlgorithm, RotatableHitBox
from arcade.types import RGBA255
from arcade.types import Color as ArcadeColor

if TYPE_CHECKING:
Expand Down Expand Up @@ -110,6 +111,21 @@ def _get_image_source(
return None


def _make_color_transparent(image: PIL.Image.Image, color: Color) -> None:
"""
Make the pixels of an RGBA image that have a color transparent, in place.

Pixels whose red, green and blue match the color become transparent
white. Their alpha doesn't matter, as in Tiled's ``transparentcolor``.
"""
# Pixels that match the color in each band, combined into one mask
mask = None
for band, value in zip(image.split()[:3], color[:3]):
matches = band.point(lambda pixel, value=value: 255 if pixel == value else 0, mode="1")
mask = matches if mask is None else PIL.ImageChops.logical_and(mask, matches)
image.paste((255, 255, 255, 0), mask=mask)


def _may_be_flip(tile: pytiled_parser.Tile, texture: Texture) -> Texture:
if tile.flipped_diagonally:
texture = texture.flip_diagonally()
Expand Down Expand Up @@ -708,20 +724,7 @@ def _process_image_layer(
)

if layer.transparent_color:
# The pillow source doesn't annotate a return type for this method, but:
# 1. The docstring does specify the returned object is sequence-like
# 2. We convert to RGBA mode implicitly in load_or_get_texture above
data: Sequence[RGBA255] = my_texture.image.getdata() # type:ignore

target = layer.transparent_color
new_data = []
for item in data:
if item[0] == target[0] and item[1] == target[1] and item[2] == target[2]:
new_data.append((255, 255, 255, 0))
else:
new_data.append(item)

my_texture.image.putdata(new_data)
_make_color_transparent(my_texture.image, layer.transparent_color)

if not custom_class:
custom_class = Sprite
Expand Down
Loading
Loading