Commit e5378bb1 authored by bzt's avatar bzt

Added collections and coloring in editor

parent 10991133
......@@ -144,8 +144,8 @@ Known Bugs
----------
Not that I know of. But no programmer can test their own code properly. I've run SSFN renderer through valgrind
with many different font files with all the tests without problems. If you find a bug, please use the Issue
Tracker on gitlab and let me know.
with many different font files with all the tests without problems. If you find a bug, please use the
[Issue Tracker](https://gitlab.com/bztsrc/scalable-font/issues) on gitlab and let me know.
Future Development (Whishlist)
------------------------------
......@@ -156,13 +156,13 @@ only stored separately if a plain letter comes first (like "Á" only splitted in
bitmap for "A" already).
The [autohinting](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/compare.md) code is very very basic
at the moment, it only use one axis partitions instead of boxes.
at the moment, it only uses one axis partitions instead of two axis partitioned boxes.
A [portable SSFN editor with GUI](https://gitlab.com/bztsrc/scalable-font/tree/master/sfnedit). I'm already on it.
It' still very early in development, you can't modify yet, but it's good enough to preview any SSFN font.
Converters only write the default glyph variants except for SSFN ASCII files where all variants are supported. The
editor is capable of editing all variant layers.
editor is capable of handling all variant layers.
Authors
-------
......
......@@ -165,7 +165,7 @@ That's all, no more dependencies. :-)
int ssfn_load(ssfn_t *ctx, ssfn_font_t *font);
```
Loads a font into the renderer context.
Loads a font or font collection into the renderer context.
### Parameters
......@@ -177,6 +177,9 @@ Loads a font into the renderer context.
You can load an SSFN file and pass it's address, or you can also use `ld -b binary` to convert an SSFN file
into an object and link that with your code. In this case you'll have a `_binary_(filename)_start` label.
You can also pass an SSFN font collection to this function, in which case all fonts within the collection
will be loaded into the context at once.
### Return value
Error code. `SSFN_ERR_BADFILE` means bad (incorrect or inconsistent) SSFN format. Hint: use `sfn2asc -d` to
......
......@@ -50,12 +50,12 @@ horizontally in the image file, and UNICODE range must be specified. If image is
image width will became the glyph's width, and image height will be divided by the size of the range,
thus giving the height of each glyph. If image is wider than tall, then image height will became glyph
height and image width divided by range size will be glyph width. For example 256 characters each with
a 16 x 16 glyph can be stored in a 16 x 4096 or in an 4096 x 16 image.
a 8 x 16 glyph can be stored in a 8 x 4096 or in an 2048 x 16 image.
Although `bit2sfn` can read true-color TGA images, I strongly suggest to convert them into indexed ones
using The Gimp: Image > Mode > Indexed... select Generate optimum palette with maximum number of 240. As
being a specific image manipulation tool, it does a lot better job in palette convertion than `bit2sfn`.
Note: if The Gimp does the aforementioned black change on its own for pixels that you want as transparency,
being a specific image manipulation tool, it does a lot better job in palette conversion than `bit2sfn`.
Note: if The Gimp does the aforementioned black change on its own for pixels that you want transparent,
then here's a workaround: select Color > Map > Rearrange Colormap to sort colors by hue (so that black
becames the first color in the palette). Then export as TGA. After that either open the TGA file in a hex
editor, and change 00 01 00 at offset 0x12 to 00 00 00, or execute this from command line (replace
......@@ -67,13 +67,13 @@ $ dd conv=notrunc if=/dev/zero of=mypixfont.tga bs=3 seek=18
Pixmaps fonts are also deduplicated the same way as bitmap fonts, and in addition they will be RLE
compressed too. The combination of these two algorithms usually yields better compression ratios than
PNG files for example (that's because SSFN does not store empty lines and it stores repeating image
blocks only once, while PNG compresses them separately).
blocks only once, while PNG compresses all occurances separately, including empty parts).
Converting SSFN ASCII Fonts
---------------------------
SSFN has a plain text, human readable "source file" format, called [ASC](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/asc_format.md).
The `bit2sfn` tool can read that and convert into a compressed binary SSFN file. The last tool, `sfn2asc` does
The `bit2sfn` tool can read that and convert into a compressed binary SSFN file. The tool `sfn2asc` does
the opposite: it converts binary SSFN fonts into plain text SSFN ASCII format. If it can found [UnicodeData.txt](http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt)
in one of /usr/share/unicode, ~/.config/ssfn, ~/.ssfn or current working directories, then the generated ASC file
will contain UNICODE code point names too in glyph definitions (which is very handy).
......@@ -119,6 +119,32 @@ copy'n'pasting glyphs and entire character ranges from one font to another. Then
Another way is to convert both fonts to ASC, and simply copy'n'paste glyph blocks with a text editor. This
is perfectly safe if the fonts have the same quality (grid size) setting.
Creating and Extracting Font Collections
----------------------------------------
There's a tool for that, `sfn2sfn`. It is very simple, expects one or more filenames on command line. If
the first file is an SSFN font, then the rest except the last must be too, and a collection will be saved
with the last file name.
```sh
$ ./sfn2sfn VeraR.sfn VeraBd.sfn VeraIt.sfn VeraBI.sfn Vera.sfn
```
If the first file is an SSFN collection, and there are no more arguments, then it lists the contents (family
code, b for bold, i for italic and unique font name). Otherwise if there're more file name arguments, it will
extract the fonts to those. With extraction, you must provide as many filenames as fonts are in the collection.
```sh
$ ./sfn2sfn Vera.sfn
1 .. Bitstream Vera Sans
1 b. Bitstream Vera Sans Bold
1 .i Bitstream Vera Sans Oblique
1 bi Bitstream Vera Sans Bold Oblique
```
```sh
$ ./sfn2sfn Vera.sfn VeraR.sfn VeraBd.sfn VeraIt.sfn VeraBI.sfn
```
Adding Hinting Grid Manually
----------------------------
......@@ -212,9 +238,8 @@ bbox_top: 0
bbox_right: 31
bbox_bottom: 31
fragments_offs: 0x00000068
fragments_num: 50
characters_offs: 0x000047e1
characters_num: 47
characters_offs[]:
0x000047e1 SSFN_VARIANT_LOCAL0 SSFN_VARIANT_DEFAULT
kerning_offs: 0x00000000
WARNING unlikely baseline value
......
......@@ -66,8 +66,8 @@ bytecode every time a glyph is rendered. Auch.
Autohinting Grid
----------------
SSFN uses a fundamentally different approach. Instead of a linear transformation, it uses a series
of contiguous linear transformations.
SSFN uses a fundamentally different approach. Instead of a single linear transformation, it uses a
series of contiguous partitions each with it's own linear transformation.
```
pixel coordinates
......@@ -84,13 +84,13 @@ pixel coordinates
0 +----o---------------o-------o------------> grid coordinates
```
Here every important grid point is pixel fitted. This guarantees that specific grid coordinates are
transformed into a discrete pixel coordinates, so antialiasing will render them sharp. To achieve
pixel fitting, SSFN does the following steps:
Here every important grid points (on partition edges) are pixel fitted. This guarantees that specific
grid coordinates are transformed into a discrete pixel coordinates, so antialiasing will render them
sharp. To achieve pixel fitting, SSFN does the following steps:
1. identify important coordinates on both X and Y axis
2. calculate the relative difference between the points on the same axis
3. create discrete pixel coordinates using the same distances but on pixel grid scale
1. identify important coordinates on the X axis
2. calculate the relative difference between those coordinates
3. create discrete pixel coordinates using the same distances but on pixel rasterization scale
4. fill in the gaps with linear sub-pixel transformations
If the SSFN font provides hinting grid information, then the first 2 steps are skipped, as the grid
......@@ -102,17 +102,29 @@ I'm unsure how ClearType works, as that's a proprietary solution with very littl
on the net. But I bet this solution beats it in speed and in accuracy!
Autohinting can be unsuccessful if the font designers are lazy or uncareful. For example in
FreeSerif the width of 't' is 184 prid pixels, while the coloumn of 'h' is 250, yet you expect
to render them with the same pixel coloumn size. Another example, in FreeSans, the right
coloumn of 'H' has different sizes on the top than on the bottom. This becames apparent when
the bottom half is pixel fitted, but the upper half remains antialiased.
The current hinting implementation is very basic, and uses only one axis. This has some drawbacks
when you render to very small sizes. Some curves that should be blurry fall into the partition edge
and therefore rendered with full pixels. This side effect becames less and less noticable as the
rendered size grows. This could be avoided with grid hinting boxes instead of one axis partitions,
where the two axis' partitions define boxes. The SSFN file format is capable of storing such info,
but this hasn't been implemented in the renderer yet.
FreeSerif the width of 't' is 184 grid pixels wide, while the coloumn of 'h' is 250 pixel wide, yet
you expect to render them with the same screen pixel width. Also the four vertical lines in
'$' have different widths, which I doubt was intentional. Another example, in FreeSans, the right
coloumn of 'H' has different widths on the top than on the bottom. This becames apparent when
the glyph is rasterized in a size when the bottom half is pixel fitted, but the upper half remains
antialiased:
```
..........
..XX..yX..
..XX..yX..
..XXXXXX..
..XX..XX..
..XX..XX..
..........
```
The current hinting implementation is very basic, and uses only one axis partitions. This has some
drawbacks when you render to very small sizes. Some curves that should be blurry fall into the
partition edge and therefore rendered with full pixels. This side effect becames less and less
noticable as the rendered size grows. This could be avoided with grid hinting boxes instead of one
axis partitions, where the two axis' partitions define boxes. The SSFN file format is capable of
storing such info, but this hasn't been implemented in the renderer yet.
```
important hint grid coordinate, starts a partition
......
......@@ -77,6 +77,21 @@ Header
If the file starts with the bytes 0x1f and 0x8b, then you have to inflate it first
using a gzip decompression filter. For command line, use `gzip -d`.
An SSFN file can contain more fonts. In this case the file starts with the header
| Offset | Length | Description |
| -----: | -----: | ----------- |
| 0 | 4 | magic, 'SFNC' |
| 4 | 4 | size of the font collection in bytes |
And concatenated fonts in SSFN format follows (with magic 'SSFN', see the header bellow).
The advantage is you can load all fonts at once with `ssfn_load()` (see
[API](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/API.md)).
A font collection does not have a separate extension or mime type, it is interpreted
within the context of the SSFN format. If compression filter is used, then it is applied
to the whole collection, and not on individual fonts.
The uncompressed file's header is the same as `ssfn_font_t` struct, see the
[API](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/API.md).
......
docs/sfnedit4.png

6.67 KB | W: | H:

docs/sfnedit4.png

10.2 KB | W: | H:

docs/sfnedit4.png
docs/sfnedit4.png
docs/sfnedit4.png
docs/sfnedit4.png
  • 2-up
  • Swipe
  • Onion skin
features.png

34.9 KB | W: | H:

features.png

36.2 KB | W: | H:

features.png
features.png
features.png
features.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -11,6 +11,8 @@ Scalable Screen Font - Example Fonts
- VeraX.sfn - vector based fonts with quadratic Bezier curves, converted from [VeraX.ttf](https://www.gnome.org/fonts/) of the GNOME Bitstream Vera Fonts (variations on style)
- Vera.sfn - an SSFN font collection of the above fonts
- u_vga16.sfn - bitmap font, converted from [u_vga16.bdf](http://www.inp.nsk.su/~bolkhov/files/fonts/univga/), made by Dmitry Bolkhovityanov
- unifont.sfn.gz bitmap font, converted from [unifont.hex](http://unifoundry.com/unifont/index.html) of the GNU unifont project
......
No preview for this file type
File added
......@@ -8,7 +8,7 @@ CFLAGS += -DHAS_UNICODE=1
LIBS = -lz
endif
all: ttf2sfn bit2sfn sfn2asc
all: ttf2sfn bit2sfn sfn2asc sfn2sfn
ttf2sfn: ttf2sfn.c
gcc $(CFLAGS) -I/usr/include/freetype2 -o $@ $< $(LIBS) -lfreetype
......@@ -19,5 +19,8 @@ bit2sfn: bit2sfn.c
sfn2asc: sfn2asc.c
gcc $(CFLAGS) -o $@ $< $(LIBS)
sfn2sfn: sfn2sfn.c
gcc $(CFLAGS) -o $@ $< $(LIBS)
clean:
@rm bit2sfn ttf2sfn sfn2asc *.o 2>/dev/null || true
@rm bit2sfn ttf2sfn sfn2asc sfn2sfn *.o 2>/dev/null || true
......@@ -8,5 +8,7 @@ Various utilities to generate and read [SSFN](https://gitlab.com/bztsrc/scalable
* bit2sfn - bitmap and pixmap font converter for PSF2 (or PSFU, Linux Console), BDF (Bitmap Disrtibution Format, X11), HEX (GNU unifont), TGA (Truevision TARGA) and [ASC](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/asc_format.md) (a plain text format)
* sfn2asc - converts an SSFN into plain ASCII text format and generates code point coverage reports
* sfn2sfn - tool to create and extract SSFN font collections
Read more details about these tools and the font formats they support in the [documentation](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/ecosystem.md).
/*
* sfnconv/sfn2sfn.c
*
* Copyright (C) 2019 bzt (bztsrc@gitlab)
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* @brief Scalable Screen Font collection utility
*
* Note: this tools handles memory allocation in a lazy fashion, but
* that's okay as it's a command line tool which exists immediately
*
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SSFN_NOIMPLEMENTATION
#include "../ssfn.h"
#if HAS_ZLIB
# include <zlib.h>
#endif
/*** variables ***/
int zip = 0;
/**
* Load a (compressed) file
*/
ssfn_font_t *load_file(char *infile, int *size)
{
ssfn_font_t *data = NULL;
long int origsize = 0;
FILE *f;
#if HAS_ZLIB
unsigned char hdr[2];
gzFile g;
#endif
f = fopen(infile,"rb");
if(!f) { fprintf(stderr,"unable to load %s\n", infile); exit(3); }
#if HAS_ZLIB
fread(&hdr, 2, 1, f);
if(hdr[0]==0x1f && hdr[1]==0x8b) {
fseek(f, -4L, SEEK_END);
fread(&origsize, 4, 1, f);
} else {
fseek(f, 0, SEEK_END);
origsize = ftell(f);
}
fclose(f);
g = gzopen(infile,"r");
#else
fseek(f, 0, SEEK_END);
origsize = ftell(f);
fseek(f, 0, SEEK_SET);
#endif
data = (ssfn_font_t*)malloc(origsize);
if(!data) { fprintf(stderr,"memory allocation error\n"); exit(2); }
#if HAS_ZLIB
gzread(g, data, origsize);
gzclose(g);
#else
fread(data, origsize, 1, f);
fclose(f);
#endif
*size = origsize;
return data;
}
/**
* Save a (compressed) file
*/
void save_file(char *outfile, ssfn_font_t *font)
{
FILE *f;
#if HAS_ZLIB
gzFile g;
#endif
#if HAS_ZLIB
if(zip) {
g = gzopen(outfile, "wb");
if(!g) { fprintf(stderr, "unable to write %s\n", outfile); exit(4); }
gzwrite(g, font, font->size);
gzclose(g);
} else
#endif
{
f = fopen(outfile, "wb");
if(!f) { fprintf(stderr, "unable to write %s\n", outfile); exit(4); }
fwrite(font, font->size, 1, f);
fclose(f);
}
}
/**
* Main procedure
*/
int main(int argc, char **argv)
{
int i;
int size = 0, total = 8;
ssfn_font_t *font, *end;
unsigned char *out = NULL;
if(argc < 2) {
printf("Scalable Screen Font by bzt Copyright (C) 2019 MIT license\n\n"
"%s "
#if HAS_ZLIB
"[-z] "
#endif
"<in sfnc> [<out ssfn 1> [<out ssfn 2> ... ]]\n"
"%s "
#if HAS_ZLIB
"[-z] "
#endif
"<in ssfn 1> [<in ssfn 2> [ ... ]] <out sfnc>\n\n"
#if HAS_ZLIB
" -z: compress output with gzip\n"
#endif
, argv[0], argv[0]);
return 1;
}
/* parse flags */
for(i=1; i<argc && argv[i][0] == '-'; i++)
if(argv[i][0] == '-' && argv[i][1] == 'z') zip = 1;
font = load_file(argv[i], &size);
if(!memcmp(font->magic, SSFN_COLLECTION, 4)) {
/* extract */
end = (ssfn_font_t*)((uint8_t*)font + font->size);
for(i++, font = (ssfn_font_t*)((uint8_t*)font + 8); font < end; font = (ssfn_font_t*)((uint8_t*)font + font->size)) {
if(argc < 3)
printf("%d %c%c %s\n", font->family,
font->style & SSFN_STYLE_BOLD ? 'b':'.', font->style & SSFN_STYLE_ITALIC ? 'i':'.',
(char*)font + sizeof(ssfn_font_t));
else
save_file(argv[i++], font);
}
} else {
/* create */
for(; i + 1 < argc; i++) {
if(!size) font = load_file(argv[i], &size);
out = (unsigned char *)realloc(out, total+size);
memcpy(out + total, font, font->size);
total += size;
size = 0;
free(font);
}
memcpy(out, SSFN_COLLECTION, 4);
memcpy(out + 4, &total, 4);
save_file(argv[i], (ssfn_font_t*)out);
}
return 0;
}
......@@ -461,7 +461,7 @@ int main(int argc, char **argv)
memset(&ssfn_hdr, 0, sizeof(ssfn_font_t));
memcpy(&ssfn_hdr.magic, SSFN_MAGIC, 4);
ssfn_hdr.size = sizeof(ssfn_font_t);
ssfn_hdr.quality = 6;
ssfn_hdr.quality = 4;
/* parse flags */
while(argv[i+1] && argv[i+1][0] == '-') {
......
......@@ -32,6 +32,7 @@
#include "file.h"
#include "ui.h"
void view_layers(ui_win_t *win);
void view_coords(ui_win_t *win);
int selcolor = 0, hue = 0, sat = 0, val = 0, incolorsel = 0;
......@@ -45,9 +46,9 @@ void rgb2hsv(uint32_t c)
m = r < g? r : g; if(b < m) m = b;
val = r > g? r : g; if(b > val) val = b;
d = val - m;
if(!val) { sat = hue = 0; return; }
if(!val) { sat = 0; return; }
sat = d * 255 / val;
if(!sat) { hue = 0; return; }
if(!sat) { return; }
if(r == val) hue = 43*(g - b) / d;
else if(g == val) hue = 85 + 43*(b - r) / d;
......@@ -85,18 +86,14 @@ uint32_t hsv2rgb(int a, int h, int s, int v)
/**
* View for color picker
*/
void view_color(ui_win_t *win, uint32_t *c)
void view_color(ui_win_t *win, uint8_t sc)
{
char tmp[4];
int i, j, p, w = (win->w - 52) / 30;
uint32_t h;
uint8_t *d, *a = (uint8_t*)&theme[THEME_INACT], *b = (uint8_t*)&theme[THEME_INPBG], *C = (uint8_t*)c;
uint32_t h, c = cmap[sc > 240 ? 240 : sc];
uint8_t *d, *a = (uint8_t*)&theme[THEME_INACT], *b = (uint8_t*)&theme[THEME_INPBG], *C = (uint8_t*)&c;
if(w < 5) w = 5;
if(selcolor == -1) {
if(!*c) selcolor = 240;
else for(selcolor=0; selcolor < 240 && cmap[selcolor] != *c; selcolor++);
}
for(j = 0; j < 8; j++)
for(i = 0; i < 30; i++) {
ui_box(win, 52 + i*w, j*w + 26, w, w, theme[selcolor == j*30+i ? THEME_INPUT : THEME_INPBG]);
......@@ -111,28 +108,28 @@ void view_color(ui_win_t *win, uint32_t *c)
} else {
ssfn_fg = theme[THEME_FG];
ui_text(win, "A ", ssfn_bg, ssfn_bg);
sprintf(tmp, "%02X", ((uint8_t*)c)[3]);
sprintf(tmp, "%02X", C[3]);
ui_scale(win, tmp, 16, 0);
ssfn_x = 52; ssfn_y += 24;
ssfn_fg = theme[THEME_FG];
ui_text(win, "R ", ssfn_bg, ssfn_bg);
sprintf(tmp, "%02X", ((uint8_t*)c)[2]);
sprintf(tmp, "%02X", C[2]);
ui_scale(win, tmp, 16, 0);
ssfn_x = 52; ssfn_y += 24;
ssfn_fg = theme[THEME_FG];
ui_text(win, "G ", ssfn_bg, ssfn_bg);
sprintf(tmp, "%02X", ((uint8_t*)c)[1]);
sprintf(tmp, "%02X", C[1]);
ui_scale(win, tmp, 16, 0);
ssfn_x = 52; ssfn_y += 24;
ssfn_fg = theme[THEME_FG];
ui_text(win, "B ", ssfn_bg, ssfn_bg);
sprintf(tmp, "%02X", ((uint8_t*)c)[0]);
sprintf(tmp, "%02X", C[0]);
ui_scale(win, tmp, 16, 0);
ssfn_y = (9*w + 26) + 2; ssfn_x += 8;
ui_box(win, ssfn_x - 4, ssfn_y - 2, 4, 260, ssfn_bg);
ui_box(win, ssfn_x +17+256+17, ssfn_y - 2, 4, 260, ssfn_bg);
for(p = ssfn_y * win->p + ssfn_x, j=0;j<256 && (int)ssfn_y + j < win->h;j++, p += win->p) {
if(((uint8_t*)c)[3] == 255-j && (int)ssfn_x < win->w && (int)ssfn_y + j + 2< win->h ) {
if(C[3] == 255-j && (int)ssfn_x < win->w && (int)ssfn_y + j + 2< win->h ) {
win->data[p - 4] = theme[THEME_INPUT];
win->data[p - 3] = theme[THEME_INPUT];
win->data[p - 2] = theme[THEME_INPUT];
......@@ -152,7 +149,7 @@ void view_color(ui_win_t *win, uint32_t *c)
((uint8_t*)&win->data[p+i])[2] = (d[2]*j + (256 - j)*C[2])>>8;
}
}
rgb2hsv(*c);
rgb2hsv(c);
for(p = ssfn_y * win->p + ssfn_x + 16, j=0;j<256 && (int)ssfn_y + j < win->h;j++, p += win->p)
for(i=0;i<256 && (int)ssfn_x + 16 + i < win->w;i++)
win->data[p + i] = sat == i || 255-j == val ? theme[i<96 && j<96 ?THEME_INPBG:THEME_INPUT] :
......@@ -180,7 +177,7 @@ void view_color(ui_win_t *win, uint32_t *c)
/**
* Controller for color picker
*/
int ctrl_color(ui_win_t *win, ui_event_t *evt, uint32_t *c)
int ctrl_color(ui_win_t *win, ui_event_t *evt, uint8_t *c)
{
int w = (win->w - 52) / 30;
uint8_t *a;
......@@ -189,23 +186,25 @@ int ctrl_color(ui_win_t *win, ui_event_t *evt, uint32_t *c)
case E_MOUSEMOVE:
if(incolorsel && selcolor < 240 && evt->y >= 30 + w*9 && evt->y < 30 + 256 + w*9) {
a = (uint8_t*)&cmap[selcolor];
if(evt->x > 117 && evt->x < 136) {
a[3] = 255 - (evt->y - w*9 - 30);
} else
if(evt->x >= 136 && evt->x < 392) {
if(!cmap[selcolor]) a[3] = 255;
sat = evt->x - 136;
val = 255 - (evt->y - w*9 - 30);
cmap[selcolor] = hsv2rgb(a[3], hue, sat, val);
} else
if(evt->x >= 392 && evt->x < 412) {
if(!cmap[selcolor]) a[3] = 255;
hue = evt->y - w*9 - 30;
if(hue >= 255) hue = 0;
cmap[selcolor] = hsv2rgb(a[3], hue, sat, val);
switch(incolorsel) {
case 1: a[3] = 255 - (evt->y - w*9 - 30); break;
case 2:
if(evt->x >= 136 && evt->x < 392) {
if(!cmap[selcolor]) a[3] = 255;
sat = evt->x - 136;
val = 255 - (evt->y - w*9 - 30);
cmap[selcolor] = hsv2rgb(a[3], hue, sat, val);
}
break;
case 3:
if(!cmap[selcolor]) a[3] = 255;
hue = evt->y - w*9 - 30;
if(hue >= 255) hue = 0;
cmap[selcolor] = hsv2rgb(a[3], hue, sat, val);
break;
}
*c = cmap[selcolor];
view_color(win, c);
*c = selcolor;
view_color(win, selcolor);
view_coords(win);
ui_flushwin(win, 0, 0, win->w, win->h);
}
......@@ -214,8 +213,8 @@ int ctrl_color(ui_win_t *win, ui_event_t *evt, uint32_t *c)
if(evt->x > 52 && evt->y > 26) {
if(evt->y < 26 + w * 9) {
selcolor = (evt->y - 26) / w * 30 + (evt->x - 52) / w;
if(selcolor > 239) { *c = 0; selcolor = 240; }
else *c = cmap[selcolor];
if(selcolor > 239) { *c = selcolor = 240; }
else *c = selcolor;
}
if(selcolor < 240 && evt->y >= 30 + w*9 && evt->y < 30 + 256 + w*9) {
a = (uint8_t*)&cmap[selcolor];
......@@ -231,26 +230,29 @@ int ctrl_color(ui_win_t *win, ui_event_t *evt, uint32_t *c)
if(evt->y >= 84 + w*9 && evt->y < 84 + 18 + w*9 && a[1] < 255) a[1]++;