def draw_keylayer(self, canvas, rect, typeface): canvas.save() if self.keylayer == Keylayer.Cmd: canvas.drawRect( skia.Rect.MakeXYWH(0, rect.h - 50, rect.w, 50), skia.Paint(AntiAlias=True, Color=hsl(0.9, l=0.25, a=0.85).skia())) canvas.drawString( "".join(self.keybuffer), 10, rect.h - 14, skia.Font(typeface, 30), skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) elif self.keylayer == Keylayer.Text: canvas.drawRect( skia.Rect.MakeXYWH(0, 0, rect.w, 50), skia.Paint(AntiAlias=True, Color=hsl(0.7, l=0.25, a=0.85).skia())) canvas.drawString( "".join(self.keybuffer), 10, 34, skia.Font(typeface, 30), skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) elif self.keylayer == Keylayer.Editing: canvas.drawRect( skia.Rect(0, 0, 50, 50), skia.Paint(AntiAlias=True, Color=hsl(0.95, l=0.5, a=0.75).skia())) canvas.restore()
def set_best_font(self): text_fits = 0 while True: text_fits += 1 font = skia.Font(skia.Typeface('Ubuntu'), text_fits) height_size = font.getSpacing() text_size = font.measureText("F#") if text_size > self.semitone_width: break self.font = skia.Font(skia.Typeface('Arial'), text_fits - 4)
def anchored_text(self, canvas, text, x: int, y: int, anchor_x: float, anchor_y: float, **kwargs): # If user sent a single string, it means a 1 item list if not isinstance(text, list): text = [text] # Get paint, font paint = kwargs.get("paint", skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) font = kwargs.get("font", skia.Font(skia.Typeface('Arial'), 24)) # Width and height of text height_size = font.getSpacing() for line_number, text_string in enumerate(text): text_size = font.measureText(text_string) # Where we'll plot the top left text according to the anchor and whatnot real_x = x - (text_size * anchor_x) real_y = y - (height_size * anchor_y) + height_size + (line_number * height_size) canvas.drawString(text_string, real_x, real_y, font, paint)
def getTextRuns(string, font, fmgr): lists = [] cRun = {'font': font, 'str': []} lst_font = font for uchar in string: codepoint = ord(uchar) glyph = lst_font.unicharToGlyph(codepoint) default_glyph = font.unicharToGlyph(codepoint) if not glyph: # We cant match with the current font lists.append(cRun) # Find new font alt_font = fmgr.matchFamilyStyleCharacter( font.getTypeface().getFamilyName(), font.getTypeface().fontStyle(), [''], codepoint) if alt_font: glyph = alt_font.unicharToGlyph(codepoint) lst_font = skia.Font(alt_font, font.getSize()) cRun = {'font': lst_font, 'str': [uchar]} else: if default_glyph == glyph and lst_font != font: lists.append(cRun) cRun = {'font': font, 'str': [uchar]} lst_font = font else: cRun['str'].append(uchar) lists.append(cRun) return lists
def draw_text(self, canvas, text_line, x_pos, y_pos, text_style=None): """ """ ## Create a list to hold Typeface constructor args typeface_args = [text_line.font] ## Append FontStyle objects to list depending on params if text_line.italic and text_line.bold: typeface_args.append(skia.FontStyle.BoldItalic()) elif text_line.bold: typeface_args.append(skia.FontStyle.Bold()) elif text_line.italic: typeface_args.append(skia.FontStyle.Italic()) ## Create FontStyle object from constructor args typeface = skia.Typeface(*typeface_args) ## Create a font and set params font = skia.Font() font.setSize(float(text_line.size)) font.setTypeface(typeface) ## Create a paint object paint = skia.Paint(self.cache_color(text_line.color)) if text_style: width = font.measureText(text_line.text) height = font.getSize() * 1.334 #! I really hate this hack x_pos -= width / 2 y_pos += height / 2 ## Draw Text Line! canvas.drawSimpleText(text_line.text, x_pos, y_pos, font, paint)
def _makeFontFromTypeface(typeface, size): font = skia.Font(typeface, size) font.setForceAutoHinting(False) font.setHinting(skia.FontHinting.kNone) font.setSubpixel(True) font.setEdging(skia.Font.Edging.kAntiAlias) return font
def test_TextBlobBuilder_allocRunRSXform(builder): font = skia.Font() xform = [ skia.RSXform(1, 0, 0, 0), skia.RSXform(1, 0, 1, 0), skia.RSXform(1, 0, 2, 0), ] builder.allocRunRSXform(font, font.textToGlyphs('foo'), xform)
def _copyFont(font): # Make a copy of a Font object. # Was hoping for a font.copy() method. tf = skia.Typeface.MakeDeserialize(font.getTypeface().serialize()) newFont = skia.Font(tf, font.getSize()) for setter, getter in _fontProperties: getattr(newFont, setter)(getattr(font, getter)()) return newFont
def test_TextBlob_MakeFromRSXform(): xform = [ skia.RSXform(1, 0, 0, 0), skia.RSXform(1, 0, 1, 0), skia.RSXform(1, 0, 2, 0), ] assert isinstance(skia.TextBlob.MakeFromRSXform('foo', xform, skia.Font()), skia.TextBlob)
def __init__(self, cachedTypefaces, _doInitialize=True): self._cachedTypefaces = cachedTypefaces self._ttFont = None self._shape = None if not _doInitialize: # self.copy() will initialize further return self.font = skia.Font(skia.Typeface(None), 10) self.font.setForceAutoHinting(False) self.font.setHinting(skia.FontHinting.kNone) self.font.setSubpixel(True) self.font.setEdging(skia.Font.Edging.kAntiAlias) self.features = {} self.variations = {}
def __init__(self, window): self.window = window self.context = skia.GrDirectContext.MakeGL() self.width, self.height = glfw.get_window_size(window) backend_render_target = skia.GrBackendRenderTarget( self.width, self.height, 0, # sampleCnt 0, # stencilBits skia.GrGLFramebufferInfo(0, GL.GL_RGBA8)) self.surface = skia.Surface.MakeFromBackendRenderTarget( self.context, backend_render_target, skia.kBottomLeft_GrSurfaceOrigin, skia.kRGBA_8888_ColorType, skia.ColorSpace.MakeSRGB()) # typeface = skia.Typeface.MakeFromFile('JetBrainsMono-Regular.ttf') self.font = skia.Font(skia.Typeface.MakeDefault(), size=40) print(self.font) self.text = skia.TextBlob.MakeFromString('drawTextBlob', self.font) self.start = time.time() assert self.surface is not None
def draw_text(text: str, point: tuple[float, float], color, *, size=40, font='Arial', align_x=Align.CENTER, align_y=Align.CENTER): if align_x not in (Align.LEFT, Align.CENTER, Align.RIGHT): raise ValueError(f"align_x bad value {align_x!r}.\nValid values are: {', '.join(map(repr, [Align.LEFT, Align.CENTER, Align.RIGHT]))}.") if align_y not in (Align.TOP, Align.CENTER, Align.BOTTOM): raise ValueError(f"align_y bad value {align_x!r}.\nValid values are: {', '.join(map(repr, [Align.TOP, Align.CENTER, Align.BOTTOM]))}.") try: cache = globals()['_text_cache'] except: cache = globals()['_text_cache'] = {} try: blob, offsets = cache[(text, font, size)] except: sfont = skia.Font(skia.Typeface(font), size) blob: skia.TextBlob = skia.TextBlob.MakeFromText(text, sfont) glyphs = sfont.textToGlyphs(text) bounds = sfont.getBounds(glyphs) positions = sfont.getXPos(glyphs) min_y = min(-b.fBottom for b in bounds) max_y = max(-b.fTop for b in bounds) # take the average of the centers as the text center center_y = sum(-b.centerY() for b in bounds) / len(bounds) min_x = positions[0] + bounds[0].fLeft max_x = positions[-1] + bounds[-1].fRight center_x = (min_x + max_x) / 2 offsets = {'min_x': min_x, 'center_x': center_x, 'max_x': max_x, 'min_y': min_y, 'center_y': center_y, 'max_y': max_y} cache[(text, font, size)] = blob, offsets x, y = point if align_x == 'left': x -= offsets['max_x'] elif align_x == 'center': x -= offsets['center_x'] elif align_x == 'right': x -= offsets['min_x'] if align_y == 'bottom': y += offsets['max_y'] elif align_y == 'center': y += offsets['center_y'] elif align_y == 'top': y += offsets['min_y'] _canvas.drawTextBlob(blob, x, y, Color._paint(color))
def draw(pen, state, data): if state != 0: return if not pen.visible: return if isinstance(pen, DATText): if isinstance(pen.style.font, str): font = skia.Typeface(pen.style.font) else: font = skia.Typeface.MakeFromFile(str(pen.style.font.path)) if len(pen.style.variations) > 0: fa = skia.FontArguments() # h/t https://github.com/justvanrossum/drawbot-skia/blob/master/src/drawbot_skia/gstate.py to_int = lambda s: struct.unpack( ">i", bytes(s, "ascii"))[0] makeCoord = skia.FontArguments.VariationPosition.Coordinate rawCoords = [ makeCoord(to_int(tag), value) for tag, value in pen.style.variations.items() ] coords = skia.FontArguments.VariationPosition.Coordinates( rawCoords) fa.setVariationDesignPosition( skia.FontArguments.VariationPosition(coords)) font = font.makeClone(fa) pt = pen.frame.point("SW") canvas.drawString( pen.text, pt.x, rect.h - pt.y, skia.Font(font, pen.style.fontSize), skia.Paint(AntiAlias=True, Color=pen.style.fill.skia())) if state == 0: SkiaPen(pen, rect, canvas, scale, style=style, alpha=pen.calc_alpha())
def test_Canvas_drawString(canvas): canvas.drawString('foo', 0, 0, skia.Font(), skia.Paint())
def test_Canvas_drawSimpleText(canvas): canvas.drawSimpleText('foo', 0, 0, skia.Font(), skia.Paint())
# ]) # def test_Canvas_drawImageLattice(canvas, image, args): # canvas.drawImageLattice(image, *args) def test_Canvas_drawSimpleText(canvas): canvas.drawSimpleText('foo', 0, 0, skia.Font(), skia.Paint()) def test_Canvas_drawString(canvas): canvas.drawString('foo', 0, 0, skia.Font(), skia.Paint()) @pytest.mark.parametrize('args', [ ( skia.TextBlob('foo', skia.Font()), 0, 0, skia.Paint(), ), ( skia.TextBlob('foo', skia.Font()), 0, 0, skia.Paint(), ), ]) def test_Canvas_drawTextBlob(canvas, args): canvas.drawTextBlob(*args)
def test_TextBlob_MakeFromPosText(): assert isinstance( skia.TextBlob.MakeFromPosText( 'foo', [skia.Point(0, 0), skia.Point(1, 0), skia.Point(2, 0)], skia.Font()), skia.TextBlob)
def textblob(): return skia.TextBlob('foo', skia.Font())
def test_Font_init(args): assert isinstance(skia.Font(*args), skia.Font)
def test_TextBlobBuilder_allocRunPos(builder): font = skia.Font() builder.allocRunPos(skia.Font(), font.textToGlyphs('foo'), [(0, 0), (1, 0), (2, 0)])
def test_TextBlobBuilder_allocRunPosH(builder): font = skia.Font() builder.allocRunPosH(font, font.textToGlyphs('foo'), [0, 1, 2], 0)
def test_TextBlobBuilder_allocRun(builder): builder.allocRun('foo', skia.Font(), 0, 0)
import skia import pytest @pytest.fixture def textblob(): return skia.TextBlob('foo', skia.Font()) @pytest.mark.parametrize('args', [ ('foo', skia.Font()), ('foo', skia.Font(), [(0, 10), (5, 10), (10, 10)]), ]) def test_TextBlob_init(args): assert isinstance(skia.TextBlob(*args), skia.TextBlob) def test_TextBlob_iter(textblob): for run in textblob: assert isinstance(run, skia.TextBlob.Iter.Run) def test_TextBlob_bounds(textblob): assert isinstance(textblob.bounds(), skia.Rect) def test_TextBlob_serialize(textblob): assert isinstance(textblob.serialize(), skia.Data) def test_TextBlob_uniqueID(textblob):
def __init__(self, **kwargs): #Defaults self.txt_font = 'Arial', self.txt_font_size = 12.0, self.uname_font = 'Arial', self.username_font_size = 13.0 self.even_bg = skia.ColorSetARGB(0xFF, 0x22, 0x22, 0x22) self.odd_bg = skia.ColorSetARGB(0xFF, 0x18, 0x18, 0x1B) self.txt_color = skia.ColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF) #Sub messages self.sub_even_bg = skia.ColorSetARGB(0xFF, 0x5C, 0x37, 0x73) self.sub_odd_bg = skia.ColorSetARGB(0xFF, 0x61, 0x3C, 0x78) self.sub_txt_color = skia.ColorSetARGB(0xFF, 0x85, 0x7F, 0x7D) #Highlighted message self.highlight_bg_color = skia.ColorSetARGB(0xFF, 0x2F, 0x21, 0x4A) self.highlight_sidebar_color = skia.ColorSetARGB( 0xFF, 0x8F, 0x49, 0xFF) self.__dict__.update((k, v) for k, v in kwargs.items() if k in DrawingOptions.allowed_opts) self.font_manager = skia.FontMgr.RefDefault() self.username_font_style = skia.FontStyle().Bold() self.text_font_style = skia.FontStyle().Normal() self.user_typeface = self.font_manager.matchFamilyStyle( self.uname_font, self.username_font_style) self.text_typeface = self.font_manager.matchFamilyStyle( self.txt_font, self.text_font_style) self.mention_typeface = self.font_manager.matchFamilyStyle( self.txt_font, skia.FontStyle().Bold()) self.text_font = skia.Font(self.text_typeface, self.txt_font_size, 1.0, 0.0) self.text_font.setSubpixel(True) self.text_font.setHinting(skia.FontHinting.kFull) self.text_font.setEdging(skia.Font.Edging.kAntiAlias) self.mention_font = skia.Font(self.mention_typeface, self.txt_font_size, 1.0, 0.0) self.user_font = skia.Font(self.user_typeface, self.uname_font_size, 1.0, 0.0) self.user_font.setSubpixel(True) self.user_font.setHinting(skia.FontHinting.kFull) self.user_font.setEdging(skia.Font.Edging.kAntiAlias) #self.user_font.setForceAutoHinting(True) if not self.text_font.getTypeface(): raise ValueError('Invalid font family specified') if not self.user_font.getTypeface(): raise ValueError('Invalid font family specified') #Suggested line distance self.spacer = self.text_font.getSpacing() self.usrPaint = skia.Paint() self.usrPaint.setAntiAlias(False) self.txtPaint = skia.Paint() self.txtPaint.setAntiAlias(False) self.txtPaint.setColor(self.txt_color) self.tstampPaint = skia.Paint() self.tstampPaint.setAntiAlias(False) self.tstampPaint.setColor(self.tstamp_color) self.usrPaint.setStrokeWidth(1) self.txtPaint.setStrokeWidth(1) self.txtPaint.setFilterQuality(skia.FilterQuality.kHigh_FilterQuality) self.usrPaint.setFilterQuality(skia.FilterQuality.kHigh_FilterQuality)
def font(): return skia.Font()
import glfw # type: ignore import skia # type: ignore import traceback import random import math import ast import importlib from dataclasses import dataclass from OpenGL import GL # type: ignore from typing import List from functools import lru_cache, wraps import numpy as np # type: ignore import matplotlib # type: ignore from buffer import Buffer font = skia.Font(skia.Typeface('Liberation Mono'), 14) line_height = font.getSpacing() col_width = font.getWidths([ord('x')])[0] @dataclass class Cell: input: Buffer output: object target_scroll = [0, 0] def clamp(l, u, v): return max(min(v, u), l)
skia.GrGLFramebufferInfo(0, GL.GL_RGBA8)) surface = skia.Surface.MakeFromBackendRenderTarget( context, backend_render_target, skia.kBottomLeft_GrSurfaceOrigin, skia.kRGBA_8888_ColorType, skia.ColorSpace.MakeSRGB()) assert surface is not None yield surface context.abandonContext() db = sqlite_utils.Database(':memory:') db['gui_status'].insert_all([{'name': 'scroll_x', 'value': 0}, {'name': 'scroll_y', 'value': 0}], pk='name') db['widget'].create({'text': str, 'x': int, 'y': int, 'width': int, 'height': int}) typeface = skia.Typeface('Arial') font = skia.Font(typeface, 14, 1, 0) font.setEdging(skia.Font.Edging.kAntiAlias) def add_widget(text): y = (db.execute('select max(y) from widget').fetchone()[0] or 0) + 30 x = 10 db['widget'].insert({'text': text, 'x': x, 'y': y, 'width': 100, 'height': 20}) with glfw_window() as window: GL.glClear(GL.GL_COLOR_BUFFER_BIT) def scroll_callback(_win, dx, dy): new_scroll_x = db['gui_status'].get('scroll_x')['value'] + dx db['gui_status'].update('scroll_x', {'value': new_scroll_x}) new_scroll_y = db['gui_status'].get('scroll_y')['value'] + dy
def test_TextBlob_MakeFromString(): assert isinstance(skia.TextBlob.MakeFromString('foo', skia.Font()), skia.TextBlob)
def test_TextBlobBuilder_make(builder): builder.allocRun('foo', skia.Font(), 0, 0) assert isinstance(builder.make(), skia.TextBlob)
def test_TextBlob_MakeFromPosTextH(): assert isinstance( skia.TextBlob.MakeFromPosTextH('foo', [0, 1, 2], 0, skia.Font()), skia.TextBlob)