Commit 3eb38e23 authored by Rahix's avatar Rahix
Browse files

feat: Add vendored ctx library

From upstream commit 35100785e2c4 ("ctx: rasterizer, micro optimizations
in rasterizer_fill_rect").

The integration is mostly a copy of pippin's original integration with
the biggest change being the use of a monospace default font.  This font
is autogenerated from lib/ctx/fira-mono.ttf at build-time so it can be
easily replaced with a different one (just overwrite said file).

git-url: https://ctx.graphics/.git

Co-developed-by: Øyvind Kolås's avatarØyvind Kolås <pippin@gimp.org>
parent 1f8e50de
#include <stdlib.h>
#include <libgen.h>
#define CTX_MAX_DRAWLIST_SIZE 4096000
#define CTX_BACKEND_TEXT 0 // we keep then non-backend code paths
// for code handling aroud, this should
// be run-time to permit doing text_to_path
#define CTX_RASTERIZER 0
#define CTX_BITPACK_PACKER 1 // pack vectors
#define CTX_BITPACK 1
#define STB_TRUETYPE_IMPLEMENTATION
#include "stb_truetype.h"
#include <sys/time.h>
#define CTX_EXTRAS 1
#define CTX_FONTS_FROM_FILE 1
#define CTX_AVX2 0
#define CTX_IMPLEMENTATION
#define CTX_PARSER 1
#include "ctx-nofont.h"
static int usage(){
fprintf (stderr, "tool to generate native ctx embedded font format\n");
fprintf (stderr, "\n");
fprintf (stderr, "usage: ctx-fontgen <file.ttf> [name [set1-set2-set3]]\n");
fprintf (stderr, "\nrecognized sets: latin1, ascii, extra, all, emoji\n");
fprintf (stderr, "\na final argument of \"binary\" might be appended, causing\nthe generated file to be binary ctx.\n");
return -1;
}
CtxDrawlist output_font={NULL,};
uint32_t glyphs[65536];
int n_glyphs = 0;
void
add_glyph (Ctx *ctx, uint32_t glyph)
{
for (int i = 0; i < n_glyphs; i++)
{
if (glyphs[i] == glyph)
return;
}
ctx_reset (ctx);
ctx_font_size (ctx, CTX_BAKE_FONT_SIZE);
ctx_move_to (ctx, 0, 0);
if (ctx_glyph (ctx, glyph, 1))
return;
glyphs[n_glyphs++] = glyph;
ctx->drawlist.flags = CTX_TRANSFORMATION_BITPACK;
ctx_drawlist_compact (&ctx->drawlist);
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (glyph, (uint8_t*)buf);
uint32_t args[2] = {glyph, ctx_glyph_width (ctx, glyph) * 256};
ctx_drawlist_add_u32 (&output_font, CTX_DEFINE_GLYPH, args);
for (int i = 3; i < ctx->drawlist.count - 1; i++)
{
CtxEntry *entry = &ctx->drawlist.entries[i];
args[0] = entry->data.u32[0];
args[1] = entry->data.u32[1];
ctx_drawlist_add_u32 (&output_font, entry->code, &args[0]);
}
}
static int find_glyph (CtxDrawlist *drawlist, uint32_t unichar)
{
for (int i = 0; i < drawlist->count; i++)
{
if (drawlist->entries[i].code == CTX_DEFINE_GLYPH &&
drawlist->entries[i].data.u32[0] == unichar)
{
return i;
// XXX this could be prone to insertion of valid header
// data in included bitmaps.. is that an issue?
}
}
fprintf (stderr, "Eeeek %i\n", unichar);
return -1;
}
int main (int argc, char **argv)
{
int binary = 0;
const char *path;
const char *name = "regular";
const char *subsets = "latin1";
Ctx *ctx;
path = argv[1];
if (!path)
{
return usage();
}
if (argv[2])
{
name = argv[2];
if (argv[3])
subsets = argv[3];
if (argv[4] && !strcmp(argv[4], "binary"))
binary=1;
}
ctx_load_font_ttf_file ("import", argv[1]);
ctx = ctx_new ();
_ctx_set_transformation (ctx, CTX_TRANSFORMATION_RELATIVE);
ctx_font (ctx, "import");
if (strstr (subsets, "all"))
for (int glyph = 0; glyph < 65536*8; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "latin1"))
for (int glyph = 0; glyph < 256; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "ascii"))
for (int glyph = 0; glyph < 127; glyph++) add_glyph (ctx, glyph);
if (strstr (subsets, "terminal"))
{
char* string = "☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼! #$%&'()*+,-.🔒"
"⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐"
"└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■"
"!#$%&'()*+,-./◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£·";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "cp437"))
{
char* string = " ☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼!\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^,`abcdefghijklmnopqrstuvwxyz{|}~⌂"
"ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»"
"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀"
"αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "vt100"))
{
char* string =
" !\"#$%&'()*+,-./0123456789:;<=>? @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_◆▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π≠£· ";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "extras"))
{
char *string =
"éñÑßæøåö£ÆÖØÅ€§π°üÜ…”““”«»©®™⭾⏎⌫·←↑↓→☀☁☂☢☭☮☯☽✉⚙⚠␣²◆♥♦♣♠÷≈±╴−╶";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
if (strstr (subsets, "emoji"))
{
char *string = "๛ ☬☣☠☀☁☂☃☢☭☮☯☼☽✉✓❤№℃∞◌◎☎☐☑♉♩♪♫♬☆◦☄☉☏☤☥☹☺☻♲♨♼♽♾⚀⚁🥕⚂⚃⚄⚅⚙⚠␣⚡⌨⌚⏏⋯•‥․‣•↺↻⌘☕✈✉✓✔✕✖✗✘☑☒☐☓✶❄❍❢❣❤❥❤❥❦❧➲㎏㎆㎅㎇㎤㎥㎦㎝㎧㎨㎞㎐㎏㎑㎒㎓㎠㎡㎢★⁈ ⁉ ⁂✵✺✽✾✿❀❁❂❉❆✡✠🤐🤑🤒🤓🤔🤕🤖🤗🤘🤙🤚🤛🤜🤝🤞🤟🤠🤡🤢🤣🤤🤥🤦🤧🤨🤩🤪🤫🤬🤭🤮🤯🤷🤸🤹🤺🥂🥇🥈🥉🥤🥨🥬🥰🥱🥳🥴🥵🥶🥺🦁🦄🦉🦊🦋🦎🦓🦔🦕🦖🦘🦙🦚🦜🦝🦟🦴🦽🦾🦿🧁🧉🧐🧙🧚🧛🧜🧟🧠🧡🧥🧤🧦🧪🧬🧭🧮🧯🧰🧱🧲🧵🧷🧸🧺🧻🛹🛸🛵🛴🛰🛬🛫🛩🛠🛣🛤🛥🛒🛏🛌🛂🛁🚶🚴🚲🚬🚩🚗🚜🚴🚘🚖🚔🚚🚑🚍🚆🚀🙈🙉🙊🙄🙃🙂🙁🙀😿😾😽😼😻😺😹😸😷😶😵😴😳😲😱😰😯😮😭😬😫😪😩😨😧😦😥😤😣😢😡😠😟😞😝😜😛😚😙😘😗😖😕😔😓😒😑😐😏😎😍😌😋😊😉😈😇😆😅😄😃😂😁😀🗝🗜🗞🗓🗒🗑🗄🖼🖤🖥🖨🖖🖕🖐🖍🖌🖋🖊🖇🕺🕹🕸🕷🕶🕵🕴🕰🕯🔭🔬🔫🔪🔩🔨🔧🔦🔥🔤🔢🔣🔡🔠🔗🔕🔔🔓🔒🔑🔐🔏🔌🔋🔊🔉🔈🔇🔅🔆📽📻📺📹📸📷📳📱📰📯📭📬📫📪📨📦📡📞📚📖📐📏📎📍📌📉📈📄📃📂📁💿💾💻💸💶💳💰💯💫💩💧💦💤💣💢💡💞💖💕💔💓💊💃💀👾👽👻👺👹👸👷👶👵👴👯👭👬👫👣👓👋👍👎🐾🐼🐻🐺🐹🐸🐷🐶🐵🐳🐲🐱🐰🐯🐮🐭🐬🐧🐦🐥🐤🐣🐢🐡🐠🐟🐞🐝🐜🐛🐙🐘🐔🐓🐒🐑🐐🐏🐎🐍🐌🐋🐊🐉🐈🐇🐆🐅🐄🐃🐂🐁🐀🏺🏹🏸🏷🏴🏳🏵🏰🏭🏬🏫🏪🏧🏢🏠🏡🏐🏍🏆🏅🏁🎼🎶🎵🎲🎰🎮🎬🎨🎧🎥🎞🎃🎄🍸🍷🍄🌿🍀🍁🍒🌵🌳🌲🌩🌪🌨🌧🌦🌥🌤🌡🌠🌟🌞🌝🌜🌛🌚🌙🌘🌗🌖🌕🌔🌓🌒🌑🌐🌏🌎🌍🌌🌋🌊🌅🌄🌂🌀";
for (const char *utf8 = string; *utf8; utf8 = ctx_utf8_skip (utf8, 1))
add_glyph (ctx, ctx_utf8_to_unichar (utf8));
}
for (int i = 0; i < n_glyphs; i++)
for (int j = 0; j < n_glyphs; j++)
{
float kerning = ctx_glyph_kern (ctx, glyphs[i], glyphs[j]);
if (kerning > 0.2)
{
CtxCommand command;
int pos = find_glyph (&output_font, glyphs[i]);
pos ++;
while (pos < output_font.count &&
output_font.entries[pos].code != CTX_DEFINE_GLYPH)
pos++;
command.code = CTX_KERNING_PAIR;
command.kern.glyph_before = glyphs[i];
command.kern.glyph_after = glyphs[j];
command.kern.amount = kerning * 256;
ctx_drawlist_insert_entry (&output_font, pos, (CtxEntry*)&command);
}
}
ctx_free (ctx);
if (!binary)
{
printf ("#ifndef CTX_FONT_%s\n", name);
printf ("/* this is a ctx encoded font based on %s */\n", basename (argv[1]));
printf ("/* CTX_SUBDIV:%i CTX_BAKE_FONT_SIZE:%i */\n", CTX_SUBDIV, CTX_BAKE_FONT_SIZE);
printf ("/* glyphs covered: \n\n");
int col = 0;
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
if (entry->code == '@')
{
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (entry->data.u32[0], (uint8_t*)buf);
switch (buf[0])
{
case '\\':
printf ("\\");
break;
default:
printf ("%s", buf);
}
col++;
if (col > 73)
{
col = 0;
printf ("\n ");
}
}
}
printf (" */\n");
printf ("static const struct __attribute__ ((packed)) {uint8_t code; uint32_t a; uint32_t b;}\nctx_font_%s[]={\n", name);
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
if (entry->code > 32 && entry->code < 127)
{
printf ("{'%c', 0x%08x, 0x%08x},", entry->code,
entry->data.u32[0],
entry->data.u32[1]);
}
else
{
printf ("{%i, 0x%08x, 0x%08x},", entry->code,
entry->data.u32[0],
entry->data.u32[1]);
}
if (entry->code == '@')
{
char buf[44]={0,0,0,0,0};
ctx_unichar_to_utf8 (entry->data.u32[0], (uint8_t*)buf);
switch (buf[0])
{
case '\\':
printf ("/* \\ x-advance: %f */", entry->data.u32[1]/256.0);
break;
default:
printf ("/* %s x-advance: %f */", buf, entry->data.u32[1]/256.0);
}
}
else
{
}
printf ("\n");
}
printf ("};\n");
printf ("#define CTX_FONT_%s 1\n", name);
printf ("#endif\n");
}
else
{
for (int i = 0; i < output_font.count; i++)
{
CtxEntry *entry = &output_font.entries[i];
for (int c = 0; c < (int)sizeof (CtxEntry); c++)
printf ("%c",((uint8_t*)(entry))[c]);
}
}
return 0;
}
This diff is collapsed.
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdint.h>
/* clang-format off */
#define CTX_MIN_EDGE_LIST_SIZE 256
#define CTX_MAX_EDGE_LIST_SIZE 512
#define CTX_MIN_JOURNAL_SIZE 512
#define CTX_MAX_JOURNAL_SIZE 512
#define CTX_LIMIT_FORMATS 1
#define CTX_DITHER 1
#define CTX_ENABLE_RGB565_BYTESWAPPED 1
#define CTX_BITPACK_PACKER 0
#define CTX_COMPOSITING_GROUPS 0
#define CTX_RENDERSTREAM_STATIC 0
#define CTX_GRADIENT_CACHE 1
#define CTX_ENABLE_CLIP 1
#define CTX_BLOATY_FAST_PATHS 0
#define CTX_1BIT_CLIP 1
#define CTX_RASTERIZER_AA 15
#define CTX_RASTERIZER_FORCE_AA 0
#define CTX_SHAPE_CACHE 0
#define CTX_SHAPE_CACHE_DIM 16*18
#define CTX_SHAPE_CACHE_ENTRIES 128
#define CTX_RASTERIZER_MAX_CIRCLE_SEGMENTS 36
#define CTX_RASTERIZER 1
#define CTX_EVENTS 0
#define CTX_STRINGPOOL_SIZE 512
#define CTX_ENABLE_SHADOW_BLUR 0
#define CTX_FORMATTER 0
#define CTX_PARSER 0
#define CTX_FONTS_FROM_FILE 0
/* clang-format on */
#define CTX_IMPLEMENTATION
/* Defining this causes the internal font to be dropped. */
#define _CTX_INTERNAL_FONT_
#include "font-fira-mono.h"
#include "ctx.h"
This diff is collapsed.
ctx.h is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
ctx.h is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with ctx; if not, see <https://www.gnu.org/licenses/>.
2002, 2012, 2015, 2019, 2020 Øyvind Kolås <pippin@gimp.org>
includes = include_directories(
'./',
)
libm_native = meson.get_compiler('c', native: true).find_library('m')
ctx_fontgen_bin = executable(
'ctx-fontgen',
'ctx-fontgen.c',
native: true,
include_directories: includes,
dependencies: libm_native,
c_args: ['-w', '-DNO_LIBCURL']
)
ctx_fontgen = generator(
ctx_fontgen_bin,
output: 'font-@BASENAME@.h',
arguments: ['@INPUT@', 'mono', 'ascii-extras'],
capture: true,
)
font = ctx_fontgen.process('fira-mono.ttf')
sources = files(
'ctx.c',
)
lib = static_library(
'ctx',
sources,
font,
include_directories: includes,
dependencies: periphdriver,
c_args: ['-O3', '-w']
)
libctx = declare_dependency(
include_directories: includes,
link_with: lib,
)
This diff is collapsed.
......@@ -8,6 +8,7 @@ subdir('./vendor/Maxim/MAX77650/')
subdir('./vendor/Maxim/MAX86150/')
subdir('./vendor/Maxim/rd117_mbed/')
subdir('./gfx/')
subdir('./ctx/')
subdir('./FreeRTOS/')
subdir('./FreeRTOS-Plus/')
......
......@@ -46,6 +46,7 @@ formatter_blacklist=(
lib/mx25lba/
lib/sdk/
lib/vendor/
lib/ctx/ctx-fontgen.c
openocd/
docker/
Documentation/hawkmoth/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment