예제 #1
0
    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
예제 #5
0
    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)
예제 #6
0
 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
예제 #7
0
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)
예제 #8
0
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
예제 #9
0
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)
예제 #10
0
    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 = {}
예제 #11
0
 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
예제 #12
0
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))
예제 #13
0
        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())
예제 #14
0
def test_Canvas_drawString(canvas):
    canvas.drawString('foo', 0, 0, skia.Font(), skia.Paint())
예제 #15
0
def test_Canvas_drawSimpleText(canvas):
    canvas.drawSimpleText('foo', 0, 0, skia.Font(), skia.Paint())
예제 #16
0
# ])
# 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)

예제 #17
0
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)
예제 #18
0
def textblob():
    return skia.TextBlob('foo', skia.Font())
예제 #19
0
def test_Font_init(args):
    assert isinstance(skia.Font(*args), skia.Font)
예제 #20
0
def test_TextBlobBuilder_allocRunPos(builder):
    font = skia.Font()
    builder.allocRunPos(skia.Font(), font.textToGlyphs('foo'), [(0, 0), (1, 0),
                                                                (2, 0)])
예제 #21
0
def test_TextBlobBuilder_allocRunPosH(builder):
    font = skia.Font()
    builder.allocRunPosH(font, font.textToGlyphs('foo'), [0, 1, 2], 0)
예제 #22
0
def test_TextBlobBuilder_allocRun(builder):
    builder.allocRun('foo', skia.Font(), 0, 0)
예제 #23
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):
예제 #24
0
    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)
예제 #25
0
def font():
    return skia.Font()
예제 #26
0
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)
예제 #27
0
        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
예제 #28
0
def test_TextBlob_MakeFromString():
    assert isinstance(skia.TextBlob.MakeFromString('foo', skia.Font()),
                      skia.TextBlob)
예제 #29
0
def test_TextBlobBuilder_make(builder):
    builder.allocRun('foo', skia.Font(), 0, 0)
    assert isinstance(builder.make(), skia.TextBlob)
예제 #30
0
def test_TextBlob_MakeFromPosTextH():
    assert isinstance(
        skia.TextBlob.MakeFromPosTextH('foo', [0, 1, 2], 0, skia.Font()),
        skia.TextBlob)