Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit da6647b

Browse filesBrowse 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 da6647b
Copy full SHA for da6647b

File tree

1 file changed

+12
-1
lines changed
Filter options

1 file changed

+12
-1
lines changed

‎src/ft2font.cpp

Copy file name to clipboardExpand all lines: src/ft2font.cpp
+12-1Lines 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_cov_merge_table{[]() {
108+
auto table = std::array<uint8_t, 0x10000>{};
109+
for (auto dst = 0; dst < 0x100; ++dst) {
110+
for (auto src = 0; src < 0x100; ++src) {
111+
table[(dst << 8) + src] = dst + src - (dst * src + 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_cov_merge_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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.