def test_methods(): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) context = cairo.Context(surface) extents = context.glyph_extents([cairo.Glyph(0, 0, 0)]) assert isinstance(extents, cairo.TextExtents) extents = context.text_extents("foo") assert isinstance(extents, cairo.TextExtents) sf = context.get_scaled_font() extents = sf.text_extents("foo") assert isinstance(extents, cairo.TextExtents) extents = sf.glyph_extents([cairo.Glyph(0, 0, 0)]) assert isinstance(extents, cairo.TextExtents)
def test_glyph(index, x, y): try: g = cairo.Glyph(index, x, y) except OverflowError: pass else: assert g.index == index assert g.x == x assert g.y == y
def layout_line(self, ctx, mastis, font_size, dpi=72): # First, cut the mastis line into kerning pairs in the order of the # utterance. kpairs = [] for i in range(len(mastis)): if (i + 1 < len(mastis)): kpairs.append((mastis[i], mastis[i + 1])) else: kpairs.append((mastis[i], None)) #print(f"kpairs = {kpairs}") # Walk down the pairs converting to a list of: # [glyph_id, x_px, y_px] lists that indicate where to place # the glyph relative to the location of the current pen. glayout = [] dx_ems = 0 dy_ems = 0 dpi_scale = dpi / 72.0 # NOTE: Validate this equation font_scale = font_size * dpi_scale x_pen, y_pen = ctx.get_current_point() for pair in kpairs: if (pair[1] is not None): kern_val_ems = self.get_kerning_for_pair(pair[0], pair[1]) else: kern_val_ems = 0 kern_val_ems = 0 current_glyph_index = self.get_glyph_index(pair[0]) current_glyph_name = self.get_glyph_name(pair[0]) current_glyph_width_ems = self.get_glyph_width(current_glyph_name) #print(f"cglyph[{pair[0]}] width: {current_glyph_width_ems}, kerning: {pair[0]}:{pair[1]}/{kern_val_ems}, dx_ems: {dx_ems}, dy_ems: {dy_ems}, kvems: {kern_val_ems}") # convert from em space to pixel space relative to the pen location. # Note: specifically written this way to minimize floating error. x_px = (dx_ems * font_scale) / self.units_per_em y_px = (dy_ems * font_scale) / self.units_per_em #print(f" '{pair[0]}': x_px: {x_px} y_px: {y_px}") glyph = cairo.Glyph(current_glyph_index, x_pen + x_px, y_pen + y_px) #print(f" glyph: {glyph}") glayout.append(glyph) # Now, figure out the advance and subtract the kerning for the # placement of the next glyph in em space. NOTE: that kerning # values are positive or negative as appropriate, so we simply # add it all together. dx_ems += current_glyph_width_ems + kern_val_ems # We don't handle vertical scripts, so ignore dy_ems. dy_ems = 0 # TODO: Need to also return extents of line (which include the kerning) # as another value, that will make all kinds of other things easier. # Like computing the proper image width, etc, etc. return glayout
def kern_test(): WIDTH = 475 HEIGHT = 128 FONT_SIZE = 30 kilta_text = "Këkketë rin in tuirachún nútokolsa li" kilta_text = "rin rin rin" kilta_text = "rin rin rin rin rin rin rin rin rin" kt = ku.KiltaTokenizer() mastis_text = kt.romanized_to_mastis(kilta_text.strip()) kf = KiltaFont("./KiThree.ttf") face = kf.get_cairo_font_face() surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT) ctx = cairo.Context(surface) ctx.set_font_face(face) ctx.set_font_size(FONT_SIZE) # font_extents is (ascent, descent, height, max_x_advance, max_y_advance) font_extents = ctx.font_extents() # fill background with white ctx.rectangle(0, 0, WIDTH, HEIGHT) ctx.set_source_rgba(1.0, 1.0, 1.0, 1.0) # white ctx.fill() # Draw unkerned text ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0) # black ctx.move_to(0, HEIGHT / 2.0 - FONT_SIZE - font_extents[1]) # descender ctx.show_text(mastis_text) line_extent = ctx.text_extents(mastis_text) print(f"Unkerned Glyph extents: {line_extent}") # Draw kerned text ctx.move_to(0, HEIGHT / 2.0) mastis_glyphs = kf.layout_line(ctx, mastis_text, FONT_SIZE) ctx.show_glyphs(mastis_glyphs) line_extent = ctx.glyph_extents(mastis_glyphs) print(f"Kerned Glyph extents: {line_extent}") # DEBUGGING ctx.move_to(WIDTH / 2.0, HEIGHT / 2.0) debug_text = kt.romanized_to_mastis("k") debug_mastis = kf.get_glyph_index(debug_text[0]) debug_glyph = [cairo.Glyph(debug_mastis, WIDTH / 2.0, HEIGHT / 2.0 + 40)] ctx.show_glyphs(debug_glyph) ext = ctx.glyph_extents(debug_glyph) print(f"ext of mastis 'k' is {ext}") # Cleanup del ctx surface.write_to_png("hello.png") del surface print("Wrote image to hello.png")
def test_context(): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) context = cairo.Context(surface) assert context.glyph_extents([(0, 0, 0)]) context.glyph_path([(0, 0, 0)]) context.show_glyphs([(0, 0, 0)]) g = cairo.Glyph(0, 0.5, 0.25) assert context.glyph_extents([g]) context.glyph_path([g]) context.show_glyphs([(0, 0, 0)])
def test_type(): assert cairo.Glyph assert issubclass(cairo.Glyph, tuple) with pytest.raises(TypeError): cairo.Glyph() g = cairo.Glyph(0, 0.5, 0.25) assert hash(g) == hash(cairo.Glyph(0, 0.5, 0.25)) assert isinstance(g, tuple) assert g == (0, 0.5, 0.25) assert g == cairo.Glyph(0, 0.5, 0.25) assert g[1] == 0.5 assert g.index == 0 assert g.x == 0.5 assert g.y == 0.25 with pytest.raises(AttributeError): assert g.z assert repr(cairo.Glyph(0, 0, 0)) == \ "cairo.Glyph(index=0, x=0.0, y=0.0)" assert str(cairo.Glyph(0, 0, 0)) == \ "cairo.Glyph(index=0, x=0.0, y=0.0)" assert eval(repr(g)) == g
def test_context(): surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) context = cairo.Context(surface) assert context.glyph_extents([(0, 0, 0)]) context.glyph_path([(0, 0, 0)]) context.show_glyphs([(0, 0, 0)]) g = cairo.Glyph(0, 0.5, 0.25) assert context.glyph_extents([g]) context.glyph_path([g]) context.show_glyphs([(0, 0, 0)]) with pytest.raises(TypeError): context.glyph_path([object()])