Skip to content

Commit

Permalink
Start binding hb-paint API
Browse files Browse the repository at this point in the history
  • Loading branch information
khaledhosny committed Jan 20, 2024
1 parent bd17e7f commit edc3d9e
Showing 1 changed file with 364 additions and 0 deletions.
364 changes: 364 additions & 0 deletions src/uharfbuzz/_harfbuzz.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,21 @@ cdef class Font:
draw_state_p = <void *>PyCapsule_GetPointer(draw_state, NULL)
hb_font_draw_glyph(self._hb_font, gid, draw_funcs._hb_drawfuncs, draw_state_p);

def paint_glyph(self, gid: int,
paint_funcs: PaintFuncs,
paint_state: object = None,
palette_index: int = 0,
foreground: int = 0x000000FF) -> None:
cdef void *paint_state_p = <void *>paint_state
if PyCapsule_IsValid(paint_state, NULL):
paint_state_p = <void *>PyCapsule_GetPointer(paint_state, NULL)
hb_font_paint_glyph(self._hb_font,
gid,
paint_funcs._hb_paintfuncs,
paint_state_p,
palette_index,
foreground)

def draw_glyph_with_pen(self, gid: int, pen):
global drawfuncs
if drawfuncs == NULL:
Expand Down Expand Up @@ -1475,6 +1490,355 @@ def ot_math_get_glyph_assembly(font: Font,
def ot_font_set_funcs(Font font):
hb_ot_font_set_funcs(font._hb_font)

class PaintCompositeMode(IntEnum):
CLEAR = HB_PAINT_COMPOSITE_MODE_CLEAR
SRC = HB_PAINT_COMPOSITE_MODE_SRC
DEST = HB_PAINT_COMPOSITE_MODE_DEST
SRC_OVER = HB_PAINT_COMPOSITE_MODE_SRC_OVER
DEST_OVER = HB_PAINT_COMPOSITE_MODE_DEST_OVER
SRC_IN = HB_PAINT_COMPOSITE_MODE_SRC_IN
DEST_IN = HB_PAINT_COMPOSITE_MODE_DEST_IN
SRC_OUT = HB_PAINT_COMPOSITE_MODE_SRC_OUT
DEST_OUT = HB_PAINT_COMPOSITE_MODE_DEST_OUT
SRC_ATOP = HB_PAINT_COMPOSITE_MODE_SRC_ATOP
DEST_ATOP = HB_PAINT_COMPOSITE_MODE_DEST_ATOP
XOR = HB_PAINT_COMPOSITE_MODE_XOR
PLUS = HB_PAINT_COMPOSITE_MODE_PLUS
SCREEN = HB_PAINT_COMPOSITE_MODE_SCREEN
OVERLAY = HB_PAINT_COMPOSITE_MODE_OVERLAY
DARKEN = HB_PAINT_COMPOSITE_MODE_DARKEN
LIGHTEN = HB_PAINT_COMPOSITE_MODE_LIGHTEN
COLOR_DODGE = HB_PAINT_COMPOSITE_MODE_COLOR_DODGE
COLOR_BURN = HB_PAINT_COMPOSITE_MODE_COLOR_BURN
HARD_LIGHT = HB_PAINT_COMPOSITE_MODE_HARD_LIGHT
SOFT_LIGHT = HB_PAINT_COMPOSITE_MODE_SOFT_LIGHT
DIFFERENCE = HB_PAINT_COMPOSITE_MODE_DIFFERENCE
EXCLUSION = HB_PAINT_COMPOSITE_MODE_EXCLUSION
MULTIPLY = HB_PAINT_COMPOSITE_MODE_MULTIPLY
HSL_HUE = HB_PAINT_COMPOSITE_MODE_HSL_HUE
HSL_SATURATION = HB_PAINT_COMPOSITE_MODE_HSL_SATURATION
HSL_COLOR = HB_PAINT_COMPOSITE_MODE_HSL_COLOR
HSL_LUMINOSITY = HB_PAINT_COMPOSITE_MODE_HSL_LUMINOSITY

cdef void _paint_push_transform_func(hb_paint_funcs_t *funcs,
void *paint_data,
float xx,
float yx,
float xy,
float yy,
float dx,
float dy,
void *user_data) noexcept:
f = <object>user_data
f(xx, yx, xy, yy, dx, dy, <object>paint_data)

cdef void _paint_pop_transform_func(hb_paint_funcs_t *funcs,
void *paint_data,
void *user_data) noexcept:
f = <object>user_data
f(<object>paint_data)

cdef hb_bool_t _paint_color_glyph_func(hb_paint_funcs_t *funcs,
void *paint_data,
hb_codepoint_t glyph,
hb_font_t *font,
void *user_data) noexcept:
f = <object>user_data
return f(<Font>font, glyph, <object>paint_data)

cdef void _paint_push_clip_glyph_func(hb_paint_funcs_t *funcs,
void *paint_data,
hb_codepoint_t glyph,
hb_font_t *font,
void *user_data) noexcept:
f = <object>user_data
f(<Font>font, glyph, <object>paint_data)

cdef void _paint_push_clip_rectangle_func(hb_paint_funcs_t *funcs,
void *paint_data,
float xmin,
float ymin,
float xmax,
float ymax,
void *user_data) noexcept:
f = <object>user_data
f(xmin, ymin, xmax, ymax, <object>paint_data)

cdef void _paint_pop_clip_func(hb_paint_funcs_t *funcs,
void *paint_data,
void *user_data) noexcept:
f = <object>user_data
f(<object>paint_data)

cdef hb_bool_t _paint_image_func(hb_paint_funcs_t *funcs,
void *paint_data,
hb_blob_t *image,
unsigned int width,
unsigned int height,
hb_tag_t format,
float slant,
hb_glyph_extents_t *extents,
void *user_data) noexcept:
f = <object>user_data
fmt = hb_tag_to_string(format, NULL)
ge = GlyphExtents(extents.x_bearing, extents.y_bearing, extents.width, extents.height)
return f(<Blob>image, width, height, fmt, slant, ge, <object>paint_data)

cdef void _paint_color_func(hb_paint_funcs_t *funcs,
void *paint_data,
hb_bool_t is_foreground,
hb_color_t color,
void *user_data) noexcept:
f = <object>user_data
f(color, is_foreground, <object>paint_data)

cdef void _paint_push_group_func(hb_paint_funcs_t *funcs,
void *paint_data,
void *user_data) noexcept:
f = <object>user_data
f(<object>paint_data)

cdef void _paint_pop_group_func(hb_paint_funcs_t *funcs,
void *paint_data,
hb_paint_composite_mode_t mode,
void *user_data) noexcept:
f = <object>user_data
m = PaintCompositeMode(mode)
f(m, <object>paint_data)

cdef class PaintFuncs:
cdef hb_paint_funcs_t* _hb_paintfuncs

def __cinit__(self):
self._hb_paintfuncs = hb_paint_funcs_create()

def __dealloc__(self):
hb_paint_funcs_destroy(self._hb_paintfuncs)

def set_push_transform_func(self,
func: Callable[[
float, # xx
float, # yx
float, # xy
float, # yy
float, # dx
float, # dy
object, # paint_data
], None],
user_data: object = None) -> None:
cdef hb_paint_push_transform_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_push_transform_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_push_transform_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_push_transform_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_pop_transform_func(self,
func: Callable[[
object, # paint_data
], None],
user_data: object = None) -> None:
cdef hb_paint_pop_transform_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_pop_transform_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_pop_transform_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_pop_transform_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_color_glyph_func(self,
func: Callable[[
Font,
int, # gid
object, # user_data
], bool],
user_data: object = None) -> None:
cdef hb_paint_color_glyph_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_color_glyph_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_color_glyph_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_color_glyph_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_push_clip_glyph_func(self,
func: Callable[[
Font,
int, # gid
object, # user_data
], bool],
user_data: object = None) -> None:
cdef hb_paint_push_clip_glyph_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_push_clip_glyph_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_push_clip_glyph_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_push_clip_glyph_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_push_clip_rectangle_func(self,
func: Callable[[
float, # xmin
float, # ymin
float, # xmax
float, # ymax
object, # user_data
], None],
user_data: object = None) -> None:
cdef hb_paint_push_clip_rectangle_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_push_clip_rectangle_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_push_clip_rectangle_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_push_clip_rectangle_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_pop_clip_func(self,
func: Callable[[
object, # user_data
], None],
user_data: object = None) -> None:
cdef hb_paint_pop_clip_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_pop_clip_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_pop_clip_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_pop_clip_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_color_func(self,
func: Callable[[
int, # color
bool, # is_foreground
object, # user_data
], None],
user_data: object = None) -> None:
cdef hb_paint_color_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_color_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_color_func
assert user_data is None, "Pass paint_state to Font.paint_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_color_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_image_func(self,
func: Callable[[
Blob, # image
int, # width
int, # height
str, # format
float, # slant
GlyphExtents, # extents
object, # user_data
], bool],
user_data: object = None) -> None:
cdef hb_paint_image_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_image_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_image_func
assert user_data is None, "Pass draw_state to Font.draw_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_image_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_push_group_func(self,
func: Callable[[
object, # user_data
], None],
user_data: object = None) -> None:
cdef hb_paint_push_group_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_push_group_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_push_group_func
assert user_data is None, "Pass draw_state to Font.draw_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_push_group_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)

def set_pop_group_func(self,
func: Callable[[
PaintCompositeMode, # mode
object, # user_data
], None],
user_data: object = None) -> None:
cdef hb_paint_pop_group_func_t func_p
cdef void *user_data_p
if PyCapsule_IsValid(func, NULL):
func_p = <hb_paint_pop_group_func_t>PyCapsule_GetPointer(func, NULL)
if PyCapsule_IsValid(user_data, NULL):
user_data_p = <void*>PyCapsule_GetPointer(user_data, NULL)
else:
user_data_p = <void*>user_data
else:
func_p = _paint_pop_group_func
assert user_data is None, "Pass draw_state to Font.draw_glyph"
user_data_p = <void*>func
hb_paint_funcs_set_pop_group_func(
self._hb_paintfuncs, func_p, user_data_p, NULL)


cdef void _move_to_func(hb_draw_funcs_t *dfuncs,
void *draw_data,
hb_draw_state_t *st,
Expand Down

0 comments on commit edc3d9e

Please sign in to comment.