Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0aaab8c

Browse files
committed
Fix alpha compositing in ft2font's draw_bitmap.
The old formula (`*dst |= *src`) works fine when either dst or src is full transparent or fully opaque, but not for compositing intermediate values. Fix that (while keeping a fast-path for the common case of writing on an empty buffer). Example (note the more uniform gray zone between the two letters): ``` from matplotlib import pyplot as plt, ft2font as f, cbook import numpy as np font = f.FT2Font(str(cbook._get_data_path("fonts/ttf/DejaVuSans.ttf"))) font.set_size(24, 72) im = f.FT2Image(30, 30) ga = font.load_char(ord("A")) gv = font.load_char(ord("V")) font.draw_glyph_to_bitmap(im, 2, 2, ga) font.draw_glyph_to_bitmap(im, 12, 2, gv) (plt.figure(layout="constrained", figsize=(3, 3)) .add_subplot(xticks=[], yticks=[]) .imshow(np.asarray(im), cmap="gray")) plt.show() ```
1 parent de00c49 commit 0aaab8c

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/ft2font.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ void FT2Image::resize(long width, long height)
104104
}
105105
}
106106

107+
static std::array<uint8_t, 0x10000> const alpha_composite_table{[]() {
108+
auto table = std::array<uint8_t, 0x10000>{};
109+
for (auto a = 0; a < 0x100; ++a) {
110+
for (auto b = 0; b < 0x100; ++b) {
111+
table[(a << 8) + b] = a + b - (a * b + 0x7f) / 0xff;
112+
}
113+
}
114+
return table;
115+
} ()};
116+
107117
void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
108118
{
109119
FT_Int image_width = (FT_Int)m_width;
@@ -124,7 +134,8 @@ void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
124134
unsigned char *dst = m_buffer + (i * image_width + x1);
125135
unsigned char *src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start);
126136
for (FT_Int j = x1; j < x2; ++j, ++dst, ++src)
127-
*dst |= *src;
137+
// Provide a fast-path for the common case of black background.
138+
*dst = *dst ? alpha_composite_table[(*dst << 8) + *src] : *src;
128139
}
129140
} else if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
130141
for (FT_Int i = y1; i < y2; ++i) {

0 commit comments

Comments
 (0)