-
Hi! I use Harfbuzz in a Python project called WeasyPrint. Code works perfectly on Linux and Mac, but sometimes fails on Windows for no obvious reason. The problem had already been explained in #3752, but it wasn’t actually fixed: the problem actually appears randomly. I decided to reproduce the problem with only C code. Here’s a program that always works on Linux but fails on Windows: #include <harfbuzz/hb.h>
#include <fontconfig/fontconfig.h>
#include <pango/pango.h>
#include <pango/pangoft2.h>
int main() {
printf("start\n");
unsigned int *length;
unsigned int count;
printf("config\n");
FcConfig *config = FcInitLoadConfigAndFonts();
PangoFontMap *font_map = pango_ft2_font_map_new();
pango_fc_font_map_set_config((PangoFcFontMap *)font_map, config);
FcConfigDestroy(config);
printf("description\n");
PangoFontDescription *font_description = pango_font_description_new();
pango_font_description_set_family(font_description, "Arial");
pango_font_description_set_style(font_description, PANGO_STYLE_NORMAL);
pango_font_description_set_stretch(font_description, PANGO_STRETCH_NORMAL);
pango_font_description_set_weight(font_description, PANGO_WEIGHT_NORMAL);
pango_font_description_set_absolute_size(font_description, 20);
printf("layout\n");
PangoContext *context = pango_font_map_create_context(font_map);
PangoLayout *layout = pango_layout_new(context);
pango_layout_set_font_description(layout, font_description);
pango_layout_set_text(layout, "test", -1);
printf("line\n");
PangoLayoutLine *line = pango_layout_get_line_readonly(layout, 0);
PangoGlyphItem *data = line->runs[0].data;
PangoFont *pango_font = data->item->analysis.font;
hb_font_t *hb_font = pango_font_get_hb_font(pango_font);
printf("get face\n");
hb_face_t *hb_face = hb_font_get_face(hb_font);
printf("reference blob\n");
hb_blob_t *hb_blob = hb_face_reference_blob(hb_face);
count = hb_face_get_glyph_count (hb_face);
printf("count: %u\n", count);
printf("get data\n");
if (hb_blob) {
printf("not null\n");
const unsigned char *blob_data = hb_blob_get_data(hb_blob, length);
/*
printf("blob: ");
for (unsigned int i = 0; i < 10; ++i) {
printf("%02X ", blob_data[i]);
}
printf("\n");
*/
printf("length: %u\n", *length);
} else {
printf("null\n");
}
} "not null" is printed, but "length" is not. I’m not even sure that it really crashes, I have no feedback from Windows, the program just stops (disclaimer: I don’t know Windows at all.) Un-commenting the blob print makes it work on Windows. I get "blob: ", and "length:" printed correctly. I’ve tried to add/remove small parts of the code (print code count, print blob…) and it sometimes work and sometimes doesn’t on Windows, for no obvious reason. It always work on Linux. Is there anything obviously wrong in my code? I use Mingw to build the executable, you can see the different builds on this page, executable files are in the artifacts. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
The Make |
Beta Was this translation helpful? Give feedback.
-
Thanks for your answer (and sorry for my terrible C level), it seems to fix the problem. And so, it means that my original problem is a mystery again… One last question: is there a case where |
Beta Was this translation helpful? Give feedback.
-
I’ve found a "solution". A Python equivalent of this code was not working on some Windows computers, hb_font_t *hb_font = pango_font_get_hb_font(pango_font);
hb_face_t *hb_face = hb_font_get_face(hb_font);
hb_blob_t *hb_blob = hb_face_reference_blob(hb_face); I’ve change my code to something like this, that works everywhere so far: PangoFontMap *font_map = pango.pango_font_get_font_map(pango_font);
hb_face_t *hb_face = pango_fc_font_map_get_hb_face((PangoFcFontMap *)font_map, (PangoFcFont *)pango_font);
hb_blob_t *hb_blob = hb_face_reference_blob(hb_face); For the record: Kozea/WeasyPrint@3a208fe I don’t want to bother you with my problem, that’s probably caused by an obscure Windows configuration detail, or a dirty race condition that nobody else will ever have in Pango/Harfbuzz. Feel free to close the discussion if you don’t want me to dig further. |
Beta Was this translation helpful? Give feedback.
The
length
you're passing tohb_blob_get_data
needs to be a pointer to an unsigned int where the function can store a result, but AFAICS you're passing an uninitialized pointer, so who knows what may happen when harfbuzz tries to store a value there. If it sometimes works on some platforms, well ... welcome to "undefined behavior".Make
length
anunsigned int
(not anunsigned int *
), and then pass its address (&length
) tohb_blob_get_data
.