Giter Site home page Giter Site logo

tinygo-org / tinyfont Goto Github PK

View Code? Open in Web Editor NEW
48.0 6.0 14.0 5.65 MB

Text library for TinyGo displays

Home Page: https://tinygo.org

License: BSD 3-Clause "New" or "Revised" License

Go 99.91% Makefile 0.09%
tinygo golang microcontroller arduino arm microbit samd21 samd51 stm32 nrf51

tinyfont's Introduction

TinyFont

Build

TinyFont is a font/text package for TinyGo displays. It is heavily based on Adafruit's GFX library.

example example

This package is experimental and may change in the future. It has not been optimized for speed or memory..

Faster compilation

During compilation, tinygo will go through all the font files in a package and them discard them if not used. To improve compilation time considerably, move the files you are going to use to a new package.

About the fonts

The fonts compiled here were just converted or made compatible, and the original authors should be given proper credit. Each font is under its own license, and while most of them are under an open license, there might be differences in its usage and conditions.

Generate your own font

You can use tinyfontgen to generate a tinyfont from a bdf/ttf font.

https://github.com/tinygo-org/tinyfont/tree/release/cmd/tinyfontgen
https://github.com/tinygo-org/tinyfont/tree/release/cmd/tinyfontgen-ttf

Incompatibility warning

This package contains incompatible changes from previous versions.

  • The argument has been changed from []byte to string.
    • You can simply add a string() cast.
  • The Font struct has been changed.
    • If you are creating your own fonts, you need to modify them.
    • You may find this script helpful for font conversion.

License

This project is licensed under the BSD 3-clause license, just like the Go project itself.

tinyfont's People

Contributors

bgould avatar conejoninja avatar deadprogram avatar rsjethani avatar sago35 avatar scraly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

tinyfont's Issues

Fonts have a severe impact on build times

I imagine this is more of a compiler issue (?), but I think it is worth noting here.

It is frustrating that including TinyFonts increases build times by 10x or more.

A partial workaround is to copy the desired font into your project, but it generally means renaming packages to make it work. (Maybe TinyGo 0.14 helps, now that it has module support.)

Add CI tests

They can just be smoke tests. Something that we can run via a Makefile would be best.

Importing "image/color" breaks scheduler=tasks

Importing "image/color" breaks scheduler=tasks:

$ tinygo version
tinygo version 0.21.0 linux/amd64 (using go version go1.17.1 and LLVM version 11.0.0)
// main.go
package main

import _ "image/color"

func main() {
}
$ tinygo flash -target arduino-mega2560 -scheduler=tasks
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.rgbaModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.rgba64Model" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.nrgbaModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.nrgba64Model" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.alphaModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.alpha16Model" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.grayModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.gray16Model" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.yCbCrModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.nYCbCrAModel" to i8*)
Invalid bitcast
i8* bitcast (%runtime._interface (i16, i8*, i8*, i8*) addrspace(1)* @"image/color.cmykModel" to i8*)

smoketest needs to be updated

Once #12 is merged, I will create a PR.

  • #10
    • Add ./examples/unicode_font
    • Add ./examples/unicode_font2
  • #12
    • Remove ./examples/pybadge
    • Remove ./examples/pyportal
    • Add ./examples/displays

Put the font data in the const area

The current dev branch code has font data in RAM.
This makes it very RAM intensive.

This issue shows how to put the font data in const, which will be done in the future.
It will also allow you to put it in spi flash afterwards.

I plan to put out a PR once I get my code together.
The PR will replace all existing fonts.

before:

var NotoEmojiRegular12pt = tinyfont.Font{
	Glyphs: []tinyfont.Glyph{
		/*  */ tinyfont.Glyph{Rune: 0x0, Width: 0x0, Height: 0x0, XAdvance: 0x10, XOffset: 0, YOffset: 0, Bitmaps: []uint8{}},
		/*  */ tinyfont.Glyph{Rune: 0xd, Width: 0x0, Height: 0x0, XAdvance: 0x10, XOffset: 0, YOffset: 0, Bitmaps: []uint8{}},
		/*   */ tinyfont.Glyph{Rune: 0x20, Width: 0x0, Height: 0x0, XAdvance: 0x10, XOffset: 0, YOffset: 0, Bitmaps: []uint8{}},
		/* # */ tinyfont.Glyph{Rune: 0x23, Width: 0xa, Height: 0xc, XAdvance: 0x10, XOffset: 3, YOffset: -11, Bitmaps: []uint8{0x19, 0x86, 0x41, 0x13, 0xff, 0x13, 0xc, 0xc3, 0x23, 0xff, 0x22, 0x9, 0x82, 0x61, 0x90}},
		/* 0 */ tinyfont.Glyph{Rune: 0x30, Width: 0x8, Height: 0xc, XAdvance: 0x10, XOffset: 4, YOffset: -10, Bitmaps: []uint8{0x3c, 0x66, 0xc2, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c}},
		/* 1 */ tinyfont.Glyph{Rune: 0x31, Width: 0x4, Height: 0xc, XAdvance: 0x10, XOffset: 6, YOffset: -11, Bitmaps: []uint8{0x37, 0x91, 0x11, 0x11, 0x11, 0x11}},
		/* 2 */ tinyfont.Glyph{Rune: 0x32, Width: 0x8, Height: 0xc, XAdvance: 0x10, XOffset: 4, YOffset: -11, Bitmaps: []uint8{0x7c, 0xc6, 0x6, 0x6, 0x6, 0x4, 0xc, 0x18, 0x30, 0x60, 0xc0, 0xff}},
		/* 3 */ tinyfont.Glyph{Rune: 0x33, Width: 0x8, Height: 0xc, XAdvance: 0x10, XOffset: 4, YOffset: -10, Bitmaps: []uint8{0x7c, 0xc6, 0x3, 0x2, 0x6, 0x38, 0x6, 0x3, 0x3, 0x3, 0x86, 0xfc}},
		// ...

after:

const cMplusConst10pt = "" +
	/*  */ "\x00\x11" + "\x00\x00\x00\x00" + "\x05\x0B" + "\x05\x00" + "\xF7" + "\x00" + "\x03\x9C\xE7\x39\xCE\x73\x80" +
	/* � */ "\x00\x11" + "\x00\x00\x00\x01" + "\x05\x0B" + "\x05\x00" + "\xF7" + "\x00" + "\x00\x00\x06\x79\x80\x00\x00" +
	/* � */ "\x00\x11" + "\x00\x00\x00\x02" + "\x05\x0B" + "\x05\x00" + "\xF7" + "\x00" + "\x02\xAA\xAA\xAA\xAA\xAA\xAA" +
	/* � */ "\x00\x11" + "\x00\x00\x00\x03" + "\x05\x0B" + "\x05\x00" + "\xF7" + "\x00" + "\x04\xBD\x29\x03\xE4\x21\x00" +
	/* � */ "\x00\x11" + "\x00\x00\x00\x04" + "\x05\x0B" + "\x05\x00" + "\xF7" + "\x00" + "\x07\xA1\xE8\x03\xD0\xF4\x00" +
	// ...

The perfect bounding box problem

While playing around with tingo+tinyfont on my adafruit clue, I wanted to create a bounding box(aka label in higher level general purpose gui programming) around a string so as to refresh the text by first re-filling the box with say black then writing string in say white. But while creating logic I noticed a few (possible) issues. To investigate further I created a small script which simply writes strings in a few selected fonts and also displays bounding box in 'red':

package main

import (
	"image/color"
	"machine"

	"tinygo.org/x/drivers/st7789"
	"tinygo.org/x/tinyfont"
	"tinygo.org/x/tinyfont/freemono"
	"tinygo.org/x/tinyfont/freesans"
	"tinygo.org/x/tinyfont/notosans"
	"tinygo.org/x/tinyfont/proggy"
)

func main() {
	machine.SPI1.Configure(machine.SPIConfig{
		Frequency: 8000000,
		SCK:       machine.TFT_SCK,
		SDO:       machine.TFT_SDO,
		SDI:       machine.TFT_SDO,
		Mode:      0,
	})

	display := st7789.New(machine.SPI1,
		machine.TFT_RESET,
		machine.TFT_DC,
		machine.TFT_CS,
		machine.TFT_LITE)

	display.Configure(st7789.Config{
		Width:        0,
		Height:       0,
		Rotation:     st7789.NO_ROTATION,
		RowOffset:    80,
		ColumnOffset: 0,
		FrameRate:    st7789.FRAMERATE_60,
		VSyncLines:   st7789.MAX_VSYNC_SCANLINES,
	})

	red := color.RGBA{100, 0, 0, 128}
	black := color.RGBA{0, 0, 0, 255}
	white := color.RGBA{255, 255, 255, 255}

	strings := map[string]*tinyfont.Font{
		"Notosans12pt":   &notosans.Notosans12pt,
		"TinySZ8pt7b":    &proggy.TinySZ8pt7b,
		"Regular12pt7bm": &freemono.Regular12pt7b,
		"Regular12pt7bs": &freesans.Regular12pt7b,
	}

	display.FillScreen(black)

	var y int16 = 10
	for str, font := range strings {
		y += int16(font.YAdvance) + 10
		_, w := tinyfont.LineWidth(font, str)
		display.FillRectangle(0, y-int16(font.YAdvance), int16(w), int16(font.YAdvance), red)
		tinyfont.WriteLine(&display, font, 0, y, str, white)
	}
}

See result in attached image

clue

Issues:

  1. Characters like p and g are sticking out of the bounding box:
  2. The bounding box for some fonts like the freesans.Regular12pt7b has lot of empty space above the characters.

Possible Reasons for issue 1:

  1. My logic of creating bounding box is wrong
  2. The Glyph values are not correct for characters like p and g

Possible Reasons for issue 2:

  1. My logic for creating bounding box is wrong.
  2. The YAdvance value for some fonts is way too high as compared to the largest YOffset in that font

PS1: I noticed that with some trial and error I can get a constant value to subtract from font.YAdvance to get prefect box with not too much extra space above the characters.

PS2: It is also possible that me as a newbie don't really understand how these fonts work and I might be trying to use them in a way they are not supposed to be used

const2bit is broken

Due to the change from Glypher to Glyph.

Attempting to use a font created by tinyfontgen-ttf and using it, yields:

main.go:31:28: cannot use font (variable of type *Font) as tinyfont.Fonter value in argument to tinyfont.WriteLine: *Font does not implement tinyfont.Fonter (wrong type for method GetGlyph)
		have GetGlyph(rune) tinyfont.Glypher
		want GetGlyph(rune) tinyfont.Glyph

Relevant code:

tinyfont.WriteLine(&ssd, TinyFont, 0, 20, "Hi there", color.RGBA{1, 0, 0, 0})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.