Finish up Core Text based rendering
This commit is contained in:
parent
8e7250eb7a
commit
426f960b23
@ -133,13 +133,13 @@ cell_size(Face *self) {
|
||||
if (w > width) width = w;
|
||||
}
|
||||
}
|
||||
return Py_BuildValue("I", width + 2); // + 2 for antialiasing which needs pixels on either side
|
||||
return Py_BuildValue("I", width);
|
||||
#undef count
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
render_char(Face *self, PyObject *args) {
|
||||
#define render_char_doc ""
|
||||
#define render_char_doc "Render the specified character into the specified buffer. Combining unicode chars should be handled automatically (I hope)"
|
||||
char *s;
|
||||
unsigned int width, height;
|
||||
PyObject *pbuf;
|
||||
@ -168,10 +168,11 @@ render_char(Face *self, PyObject *args) {
|
||||
CGContextSetTextDrawingMode(ctx, kCGTextFill);
|
||||
CGGlyph glyph = glyphs[0];
|
||||
if (glyph) {
|
||||
CGRect rect = CTFontGetBoundingRectsForGlyphs(font, kCTFontOrientationHorizontal, glyphs, 0, 1);
|
||||
// TODO: Scale the glyph if its bbox is larger than the image by using a non-identity transform
|
||||
/* CGRect rect = CTFontGetBoundingRectsForGlyphs(font, kCTFontOrientationHorizontal, glyphs, 0, 1); */
|
||||
CGContextSetTextMatrix(ctx, transform);
|
||||
CGFloat pos_x = -rect.origin.x + 1, pos_y = height - rect.origin.y - rect.size.height;
|
||||
CGFloat leading = self->leading > 0 ? self->leading : 1; // Ensure at least one pixel of leading so that antialiasing works at the left edge
|
||||
CGFloat pos_x = leading, pos_y = height - self->ascent;
|
||||
CGContextSetTextPosition(ctx, pos_x, pos_y);
|
||||
CTFontDrawGlyphs(font, &glyph, &CGPointZero, 1, ctx);
|
||||
}
|
||||
|
||||
@ -22,11 +22,10 @@ def set_font_family(family, size_in_pts):
|
||||
mf = main_font[(False, False)]
|
||||
cell_width = mf.cell_size()
|
||||
cell_height = ceil_int(mf.ascent + mf.descent)
|
||||
cell_height += 1 * int(round(dpi / 72.0)) # some line spacing
|
||||
CellTexture = ctypes.c_ubyte * (cell_width * cell_height)
|
||||
WideCellTexture = ctypes.c_ubyte * (2 * cell_width * cell_height)
|
||||
baseline = int(round(mf.ascent))
|
||||
underline_position = int(round(mf.underline_position))
|
||||
underline_position = int(round(baseline - mf.underline_position))
|
||||
underline_thickness = ceil_int(mf.underline_thickness)
|
||||
return cell_width, cell_height
|
||||
|
||||
@ -35,6 +34,16 @@ def current_cell():
|
||||
return CellTexture, cell_width, cell_height, baseline, underline_thickness, underline_position
|
||||
|
||||
|
||||
def split(buf, cell_width, cell_height):
|
||||
first, second = CellTexture(), CellTexture()
|
||||
for y in range(cell_height):
|
||||
offset, woffset = y * cell_width, y * cell_width * 2
|
||||
for x in range(cell_width):
|
||||
first[offset + x] = buf[woffset + x]
|
||||
second[offset + x] = buf[woffset + cell_width + x]
|
||||
return first, second
|
||||
|
||||
|
||||
def render_cell(text=' ', bold=False, italic=False):
|
||||
width = wcwidth(text[0])
|
||||
face = main_font[(bold, italic)]
|
||||
@ -43,15 +52,24 @@ def render_cell(text=' ', bold=False, italic=False):
|
||||
else:
|
||||
buf, width = CellTexture(), cell_width
|
||||
face.render_char(text, width, cell_height, ctypes.addressof(buf))
|
||||
if width == 2:
|
||||
first, second = split(buf, cell_width, cell_height)
|
||||
else:
|
||||
first, second = buf, None
|
||||
return first, second
|
||||
|
||||
|
||||
def develop():
|
||||
def develop(sz=288):
|
||||
import pickle
|
||||
from kitty.fast_data_types import glfw_init
|
||||
from .render import render_string
|
||||
glfw_init()
|
||||
set_font_family('monospace', 12.0)
|
||||
set_font_family('monospace', sz)
|
||||
for (bold, italic), face in main_font.items():
|
||||
print('bold: {} italic: {} family:{} full name: {}'.format(bold, italic, face.family_name, face.full_name))
|
||||
f = main_font[(False, False)]
|
||||
for attr in 'units_per_em ascent descent leading underline_position underline_thickness scaled_point_sz'.split():
|
||||
print(attr, getattr(f, attr))
|
||||
print('cell_width: {}, cell_height: {}, baseline: {}'.format(cell_width, cell_height, baseline))
|
||||
buf, w, h = render_string(sz=200)
|
||||
open('/tmp/cell.data', 'wb').write(pickle.dumps((bytearray(buf), w, h)))
|
||||
|
||||
@ -76,7 +76,7 @@ def display_bitmap(data, w, h):
|
||||
img.show()
|
||||
|
||||
|
||||
def test_rendering(text='\'Ping👁a⧽', sz=144, family='Ubuntu Mono for Kovid'):
|
||||
def render_string(text='\'Qing👁a⧽', sz=144, family='monospace'):
|
||||
set_font_family(family, sz)
|
||||
cells = []
|
||||
for c in text:
|
||||
@ -86,4 +86,8 @@ def test_rendering(text='\'Ping👁a⧽', sz=144, family='Ubuntu Mono for Kov
|
||||
cells.append(s)
|
||||
cell_width, cell_height = current_cell()[1:3]
|
||||
char_data = join_cells(cell_width, cell_height, *cells)
|
||||
display_bitmap(char_data, cell_width * len(cells), cell_height)
|
||||
return char_data, cell_width * len(cells), cell_height
|
||||
|
||||
|
||||
def test_rendering(text='\'Ping👁a⧽', sz=144, family='monospace'):
|
||||
display_bitmap(*render_string(text, sz, family))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user