459 lines
15 KiB
Python
459 lines
15 KiB
Python
"""Imports of dynamic libraries used for text layout."""
|
|
|
|
import os
|
|
from contextlib import suppress
|
|
|
|
import cffi
|
|
|
|
ffi = cffi.FFI()
|
|
ffi.cdef('''
|
|
// HarfBuzz
|
|
|
|
typedef ... hb_font_t;
|
|
typedef ... hb_face_t;
|
|
typedef ... hb_blob_t;
|
|
typedef uint32_t hb_codepoint_t;
|
|
hb_face_t * hb_font_get_face (hb_font_t *font);
|
|
hb_blob_t * hb_face_reference_blob (hb_face_t *face);
|
|
unsigned int hb_face_get_index (const hb_face_t *face);
|
|
unsigned int hb_face_get_upem (const hb_face_t *face);
|
|
const char * hb_blob_get_data (hb_blob_t *blob, unsigned int *length);
|
|
bool hb_ot_color_has_png (hb_face_t *face);
|
|
hb_blob_t * hb_ot_color_glyph_reference_png (
|
|
hb_font_t *font, hb_codepoint_t glyph);
|
|
bool hb_ot_color_has_svg (hb_face_t *face);
|
|
hb_blob_t * hb_ot_color_glyph_reference_svg (
|
|
hb_face_t *face, hb_codepoint_t glyph);
|
|
void hb_blob_destroy (hb_blob_t *blob);
|
|
|
|
|
|
// Pango
|
|
|
|
typedef unsigned int guint;
|
|
typedef int gint;
|
|
typedef char gchar;
|
|
typedef gint gboolean;
|
|
typedef void* gpointer;
|
|
typedef ... PangoLayout;
|
|
typedef ... PangoContext;
|
|
typedef ... PangoFontMap;
|
|
typedef ... PangoFontMetrics;
|
|
typedef ... PangoLanguage;
|
|
typedef ... PangoTabArray;
|
|
typedef ... PangoFontDescription;
|
|
typedef ... PangoLayoutIter;
|
|
typedef ... PangoAttrList;
|
|
typedef ... PangoAttrClass;
|
|
typedef ... PangoFont;
|
|
typedef guint PangoGlyph;
|
|
typedef gint PangoGlyphUnit;
|
|
|
|
const guint PANGO_GLYPH_EMPTY = 0x0FFFFFFF;
|
|
const guint PANGO_GLYPH_UNKNOWN_FLAG = 0x10000000;
|
|
|
|
typedef enum {
|
|
PANGO_STYLE_NORMAL,
|
|
PANGO_STYLE_OBLIQUE,
|
|
PANGO_STYLE_ITALIC
|
|
} PangoStyle;
|
|
|
|
typedef enum {
|
|
PANGO_WEIGHT_THIN = 100,
|
|
PANGO_WEIGHT_ULTRALIGHT = 200,
|
|
PANGO_WEIGHT_LIGHT = 300,
|
|
PANGO_WEIGHT_BOOK = 380,
|
|
PANGO_WEIGHT_NORMAL = 400,
|
|
PANGO_WEIGHT_MEDIUM = 500,
|
|
PANGO_WEIGHT_SEMIBOLD = 600,
|
|
PANGO_WEIGHT_BOLD = 700,
|
|
PANGO_WEIGHT_ULTRABOLD = 800,
|
|
PANGO_WEIGHT_HEAVY = 900,
|
|
PANGO_WEIGHT_ULTRAHEAVY = 1000
|
|
} PangoWeight;
|
|
|
|
typedef enum {
|
|
PANGO_FONT_MASK_SIZE = 1 << 5,
|
|
PANGO_FONT_MASK_GRAVITY = 1 << 6,
|
|
PANGO_FONT_MASK_VARIATIONS = 1 << 7
|
|
} PangoFontMask;
|
|
|
|
typedef enum {
|
|
PANGO_STRETCH_ULTRA_CONDENSED,
|
|
PANGO_STRETCH_EXTRA_CONDENSED,
|
|
PANGO_STRETCH_CONDENSED,
|
|
PANGO_STRETCH_SEMI_CONDENSED,
|
|
PANGO_STRETCH_NORMAL,
|
|
PANGO_STRETCH_SEMI_EXPANDED,
|
|
PANGO_STRETCH_EXPANDED,
|
|
PANGO_STRETCH_EXTRA_EXPANDED,
|
|
PANGO_STRETCH_ULTRA_EXPANDED
|
|
} PangoStretch;
|
|
|
|
typedef enum {
|
|
PANGO_WRAP_WORD,
|
|
PANGO_WRAP_CHAR,
|
|
PANGO_WRAP_WORD_CHAR
|
|
} PangoWrapMode;
|
|
|
|
typedef enum {
|
|
PANGO_TAB_LEFT
|
|
} PangoTabAlign;
|
|
|
|
typedef enum {
|
|
PANGO_ELLIPSIZE_NONE,
|
|
PANGO_ELLIPSIZE_START,
|
|
PANGO_ELLIPSIZE_MIDDLE,
|
|
PANGO_ELLIPSIZE_END
|
|
} PangoEllipsizeMode;
|
|
|
|
typedef struct GSList {
|
|
gpointer data;
|
|
struct GSList *next;
|
|
} GSList;
|
|
|
|
typedef struct {
|
|
void *shape_engine;
|
|
void *lang_engine;
|
|
PangoFont *font;
|
|
guint level;
|
|
guint gravity;
|
|
guint flags;
|
|
guint script;
|
|
PangoLanguage *language;
|
|
GSList *extra_attrs;
|
|
} PangoAnalysis;
|
|
|
|
typedef struct {
|
|
gint offset;
|
|
gint length;
|
|
gint num_chars;
|
|
PangoAnalysis analysis;
|
|
} PangoItem;
|
|
|
|
typedef struct {
|
|
PangoGlyphUnit width;
|
|
PangoGlyphUnit x_offset;
|
|
PangoGlyphUnit y_offset;
|
|
} PangoGlyphGeometry;
|
|
|
|
typedef struct {
|
|
guint is_cluster_start : 1;
|
|
} PangoGlyphVisAttr;
|
|
|
|
typedef struct {
|
|
PangoGlyph glyph;
|
|
PangoGlyphGeometry geometry;
|
|
PangoGlyphVisAttr attr;
|
|
} PangoGlyphInfo;
|
|
|
|
typedef struct {
|
|
gint num_glyphs;
|
|
PangoGlyphInfo *glyphs;
|
|
gint *log_clusters;
|
|
} PangoGlyphString;
|
|
|
|
typedef struct {
|
|
PangoItem *item;
|
|
PangoGlyphString *glyphs;
|
|
} PangoGlyphItem;
|
|
|
|
typedef struct GSListRuns {
|
|
PangoGlyphItem *data;
|
|
struct GSListRuns *next;
|
|
} GSListRuns;
|
|
|
|
typedef struct {
|
|
const PangoAttrClass *klass;
|
|
guint start_index;
|
|
guint end_index;
|
|
} PangoAttribute;
|
|
|
|
typedef struct {
|
|
PangoLayout *layout;
|
|
gint start_index;
|
|
gint length;
|
|
GSListRuns *runs;
|
|
guint is_paragraph_start : 1;
|
|
guint resolved_dir : 3;
|
|
} PangoLayoutLine;
|
|
|
|
typedef struct {
|
|
int x;
|
|
int y;
|
|
int width;
|
|
int height;
|
|
} PangoRectangle;
|
|
|
|
typedef struct {
|
|
guint is_line_break: 1;
|
|
guint is_mandatory_break : 1;
|
|
guint is_char_break : 1;
|
|
guint is_white : 1;
|
|
guint is_cursor_position : 1;
|
|
guint is_word_start : 1;
|
|
guint is_word_end : 1;
|
|
guint is_sentence_boundary : 1;
|
|
guint is_sentence_start : 1;
|
|
guint is_sentence_end : 1;
|
|
guint backspace_deletes_character : 1;
|
|
guint is_expandable_space : 1;
|
|
guint is_word_boundary : 1;
|
|
} PangoLogAttr;
|
|
|
|
int pango_version (void);
|
|
|
|
double pango_units_to_double (int i);
|
|
int pango_units_from_double (double d);
|
|
void g_object_unref (gpointer object);
|
|
void g_type_init (void);
|
|
|
|
PangoLayout * pango_layout_new (PangoContext *context);
|
|
void pango_layout_set_width (PangoLayout *layout, int width);
|
|
PangoAttrList * pango_layout_get_attributes(PangoLayout *layout);
|
|
void pango_layout_set_attributes (
|
|
PangoLayout *layout, PangoAttrList *attrs);
|
|
void pango_layout_set_text (
|
|
PangoLayout *layout, const char *text, int length);
|
|
void pango_layout_set_tabs (
|
|
PangoLayout *layout, PangoTabArray *tabs);
|
|
void pango_layout_set_font_description (
|
|
PangoLayout *layout, const PangoFontDescription *desc);
|
|
void pango_layout_set_wrap (
|
|
PangoLayout *layout, PangoWrapMode wrap);
|
|
void pango_layout_set_single_paragraph_mode (
|
|
PangoLayout *layout, gboolean setting);
|
|
int pango_layout_get_baseline (PangoLayout *layout);
|
|
PangoLayoutLine * pango_layout_get_line_readonly (
|
|
PangoLayout *layout, int line);
|
|
|
|
hb_font_t * pango_font_get_hb_font (PangoFont *font);
|
|
|
|
PangoFontDescription * pango_font_description_new (void);
|
|
void pango_font_description_free (PangoFontDescription *desc);
|
|
PangoFontDescription * pango_font_description_copy (
|
|
const PangoFontDescription *desc);
|
|
|
|
void pango_font_description_set_family (
|
|
PangoFontDescription *desc, const char *family);
|
|
void pango_font_description_set_style (
|
|
PangoFontDescription *desc, PangoStyle style);
|
|
void pango_font_description_set_stretch (
|
|
PangoFontDescription *desc, PangoStretch stretch);
|
|
void pango_font_description_set_weight (
|
|
PangoFontDescription *desc, PangoWeight weight);
|
|
void pango_font_description_set_absolute_size (
|
|
PangoFontDescription *desc, double size);
|
|
void pango_font_description_set_variations (
|
|
PangoFontDescription* desc, const char* variations);
|
|
|
|
PangoStyle pango_font_description_get_style (
|
|
const PangoFontDescription *desc);
|
|
const char* pango_font_description_get_variations (
|
|
const PangoFontDescription* desc);
|
|
PangoWeight pango_font_description_get_weight (
|
|
const PangoFontDescription* desc);
|
|
int pango_font_description_get_size (PangoFontDescription *desc);
|
|
|
|
void pango_font_description_unset_fields (
|
|
PangoFontDescription* desc, PangoFontMask to_unset);
|
|
|
|
int pango_glyph_string_get_width (PangoGlyphString *glyphs);
|
|
char * pango_font_description_to_string (
|
|
const PangoFontDescription *desc);
|
|
|
|
PangoFontDescription * pango_font_describe (PangoFont *font);
|
|
const char * pango_font_description_get_family (
|
|
const PangoFontDescription *desc);
|
|
guint pango_font_description_hash (const PangoFontDescription *desc);
|
|
|
|
PangoContext * pango_context_new ();
|
|
PangoContext * pango_font_map_create_context (PangoFontMap *fontmap);
|
|
|
|
PangoFont* pango_font_map_load_font (
|
|
PangoFontMap* fontmap, PangoContext* context,
|
|
const PangoFontDescription* desc);
|
|
|
|
PangoFontMetrics * pango_context_get_metrics (
|
|
PangoContext *context, const PangoFontDescription *desc,
|
|
PangoLanguage *language);
|
|
PangoFontMetrics * pango_font_get_metrics (
|
|
PangoFont *font, PangoLanguage *language);
|
|
void pango_font_metrics_unref (PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_ascent (PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_descent (PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_underline_thickness (
|
|
PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_underline_position (
|
|
PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_strikethrough_thickness (
|
|
PangoFontMetrics *metrics);
|
|
int pango_font_metrics_get_strikethrough_position (
|
|
PangoFontMetrics *metrics);
|
|
void pango_font_get_glyph_extents (
|
|
PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect,
|
|
PangoRectangle *logical_rect);
|
|
|
|
void pango_context_set_round_glyph_positions (
|
|
PangoContext *context, gboolean round_positions);
|
|
|
|
PangoAttrList * pango_attr_list_new (void);
|
|
void pango_attr_list_unref (PangoAttrList *list);
|
|
void pango_attr_list_insert (
|
|
PangoAttrList *list, PangoAttribute *attr);
|
|
void pango_attr_list_change (
|
|
PangoAttrList *list, PangoAttribute *attr);
|
|
PangoAttribute * pango_attr_font_features_new (const gchar *features);
|
|
PangoAttribute * pango_attr_letter_spacing_new (int letter_spacing);
|
|
PangoAttribute * pango_attr_insert_hyphens_new (gboolean insert_hyphens);
|
|
void pango_attribute_destroy (PangoAttribute *attr);
|
|
|
|
PangoTabArray * pango_tab_array_new_with_positions (
|
|
gint size, gboolean positions_in_pixels, PangoTabAlign first_alignment,
|
|
gint first_position, ...);
|
|
void pango_tab_array_free (PangoTabArray *tab_array);
|
|
|
|
PangoLanguage * pango_language_from_string (const char *language);
|
|
PangoLanguage * pango_language_get_default (void);
|
|
void pango_context_set_language (
|
|
PangoContext *context, PangoLanguage *language);
|
|
void pango_context_set_font_map (
|
|
PangoContext *context, PangoFontMap *font_map);
|
|
|
|
void pango_layout_line_get_extents (
|
|
PangoLayoutLine *line,
|
|
PangoRectangle *ink_rect, PangoRectangle *logical_rect);
|
|
|
|
PangoContext * pango_layout_get_context (PangoLayout *layout);
|
|
void pango_layout_set_ellipsize (
|
|
PangoLayout *layout,
|
|
PangoEllipsizeMode ellipsize);
|
|
|
|
void pango_get_log_attrs (
|
|
const char *text, int length, int level, PangoLanguage *language,
|
|
PangoLogAttr *log_attrs, int attrs_len);
|
|
|
|
|
|
// FontConfig
|
|
|
|
typedef int FcBool;
|
|
typedef struct _FcConfig FcConfig;
|
|
typedef struct _FcPattern FcPattern;
|
|
typedef struct _FcStrList FcStrList;
|
|
typedef unsigned char FcChar8;
|
|
|
|
typedef enum {
|
|
FcResultMatch, FcResultNoMatch, FcResultTypeMismatch, FcResultNoId,
|
|
FcResultOutOfMemory
|
|
} FcResult;
|
|
|
|
typedef enum {
|
|
FcMatchPattern, FcMatchFont, FcMatchScan
|
|
} FcMatchKind;
|
|
|
|
typedef struct _FcFontSet {
|
|
int nfont;
|
|
int sfont;
|
|
FcPattern **fonts;
|
|
} FcFontSet;
|
|
|
|
typedef enum _FcSetName {
|
|
FcSetSystem = 0,
|
|
FcSetApplication = 1
|
|
} FcSetName;
|
|
|
|
FcConfig * FcInitLoadConfigAndFonts (void);
|
|
void FcConfigDestroy (FcConfig *config);
|
|
FcBool FcConfigAppFontAddFile (
|
|
FcConfig *config, const FcChar8 *file);
|
|
FcConfig * FcConfigGetCurrent (void);
|
|
FcBool FcConfigSetCurrent (FcConfig *config);
|
|
FcBool FcConfigParseAndLoad (
|
|
FcConfig *config, const FcChar8 *file, FcBool complain);
|
|
|
|
FcFontSet * FcConfigGetFonts(FcConfig *config, FcSetName set);
|
|
FcStrList * FcConfigGetConfigFiles(FcConfig *config);
|
|
FcChar8 * FcStrListNext(FcStrList *list);
|
|
|
|
void FcDefaultSubstitute (FcPattern *pattern);
|
|
FcBool FcConfigSubstitute (
|
|
FcConfig *config, FcPattern *p, FcMatchKind kind);
|
|
|
|
FcPattern * FcPatternCreate (void);
|
|
FcPattern * FcPatternDestroy (FcPattern *p);
|
|
FcBool FcPatternAddString (
|
|
FcPattern *p, const char *object, const FcChar8 *s);
|
|
FcResult FcPatternGetString (
|
|
FcPattern *p, const char *object, int n, FcChar8 **s);
|
|
FcPattern * FcFontMatch (
|
|
FcConfig *config, FcPattern *p, FcResult *result);
|
|
|
|
|
|
// PangoFT2
|
|
|
|
typedef ... PangoFcFontMap;
|
|
|
|
PangoFontMap * pango_ft2_font_map_new (void);
|
|
void pango_fc_font_map_set_config (
|
|
PangoFcFontMap *fcfontmap, FcConfig *fcconfig);
|
|
void pango_fc_font_map_config_changed (PangoFcFontMap *fcfontmap);
|
|
''')
|
|
|
|
|
|
def _dlopen(ffi, *names):
|
|
"""Try various names for the same library, for different platforms."""
|
|
for name in names:
|
|
with suppress(OSError):
|
|
return ffi.dlopen(name)
|
|
# Re-raise the exception.
|
|
print(
|
|
'\n-----\n\n'
|
|
'WeasyPrint could not import some external libraries. Please '
|
|
'carefully follow the installation steps before reporting an issue:\n'
|
|
'https://doc.courtbouillon.org/weasyprint/stable/'
|
|
'first_steps.html#installation\n'
|
|
'https://doc.courtbouillon.org/weasyprint/stable/'
|
|
'first_steps.html#troubleshooting',
|
|
'\n\n-----\n') # pragma: no cover
|
|
return ffi.dlopen(names[0]) # pragma: no cover
|
|
|
|
|
|
if hasattr(os, 'add_dll_directory'): # pragma: no cover
|
|
dll_directories = os.getenv(
|
|
'WEASYPRINT_DLL_DIRECTORIES',
|
|
'C:\\Program Files\\GTK3-Runtime Win64\\bin').split(';')
|
|
for dll_directory in dll_directories:
|
|
with suppress((OSError, FileNotFoundError)):
|
|
os.add_dll_directory(dll_directory)
|
|
|
|
gobject = _dlopen(
|
|
ffi, 'gobject-2.0-0', 'gobject-2.0', 'libgobject-2.0-0',
|
|
'libgobject-2.0.so.0', 'libgobject-2.0.dylib', 'libgobject-2.0-0.dll')
|
|
pango = _dlopen(
|
|
ffi, 'pango-1.0-0', 'pango-1.0', 'libpango-1.0-0', 'libpango-1.0.so.0',
|
|
'libpango-1.0.dylib', 'libpango-1.0-0.dll')
|
|
harfbuzz = _dlopen(
|
|
ffi, 'harfbuzz', 'harfbuzz-0.0', 'libharfbuzz-0',
|
|
'libharfbuzz.so.0', 'libharfbuzz.so.0', 'libharfbuzz.0.dylib',
|
|
'libharfbuzz-0.dll')
|
|
fontconfig = _dlopen(
|
|
ffi, 'fontconfig-1', 'fontconfig', 'libfontconfig', 'libfontconfig.so.1',
|
|
'libfontconfig.1.dylib', 'libfontconfig-1.dll')
|
|
pangoft2 = _dlopen(
|
|
ffi, 'pangoft2-1.0-0', 'pangoft2-1.0', 'libpangoft2-1.0-0',
|
|
'libpangoft2-1.0.so.0', 'libpangoft2-1.0.dylib', 'libpangoft2-1.0-0.dll')
|
|
|
|
gobject.g_type_init()
|
|
|
|
units_to_double = pango.pango_units_to_double
|
|
units_from_double = pango.pango_units_from_double
|
|
|
|
|
|
def unicode_to_char_p(string):
|
|
"""Return ``(pointer, bytestring)``.
|
|
|
|
The byte string must live at least as long as the pointer is used.
|
|
|
|
"""
|
|
bytestring = string.encode().replace(b'\x00', b'')
|
|
return ffi.new('char[]', bytestring), bytestring
|