| @@ -98,14 +98,14 @@ static unsigned int conio_get_window_height(caca_t *kk) | |||||
| static void conio_display(caca_t *kk) | static void conio_display(caca_t *kk) | ||||
| { | { | ||||
| char *screen = kk->drv.p->screen; | char *screen = kk->drv.p->screen; | ||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
| int n; | int n; | ||||
| for(n = kk->qq->height * kk->qq->width; n--; ) | for(n = kk->qq->height * kk->qq->width; n--; ) | ||||
| { | { | ||||
| *screen++ = _cucul_utf32_to_cp437(*chars++); | *screen++ = _cucul_utf32_to_cp437(*chars++); | ||||
| *screen++ = *attr++; | |||||
| *screen++ = _cucul_rgba32_to_ansi8(*attr++); | |||||
| } | } | ||||
| # if defined(SCREENUPDATE_IN_PC_H) | # if defined(SCREENUPDATE_IN_PC_H) | ||||
| ScreenUpdate(kk->drv.p->screen); | ScreenUpdate(kk->drv.p->screen); | ||||
| @@ -245,12 +245,12 @@ static void gl_display(caca_t *kk) | |||||
| line = 0; | line = 0; | ||||
| for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | ||||
| { | { | ||||
| uint8_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| uint32_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | ||||
| { | { | ||||
| glDisable(GL_TEXTURE_2D); | glDisable(GL_TEXTURE_2D); | ||||
| glColor4bv(gl_bgpal[attr[0] >> 4]); | |||||
| glColor4bv(gl_bgpal[_cucul_rgba32_to_ansi4bg(*attr++)]); | |||||
| glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||||
| glVertex2f(x, y); | glVertex2f(x, y); | ||||
| glVertex2f(x + kk->drv.p->font_width, y); | glVertex2f(x + kk->drv.p->font_width, y); | ||||
| @@ -258,8 +258,6 @@ static void gl_display(caca_t *kk) | |||||
| y + kk->drv.p->font_height); | y + kk->drv.p->font_height); | ||||
| glVertex2f(x, y + kk->drv.p->font_height); | glVertex2f(x, y + kk->drv.p->font_height); | ||||
| glEnd(); | glEnd(); | ||||
| attr++; | |||||
| } | } | ||||
| line++; | line++; | ||||
| @@ -273,7 +271,7 @@ static void gl_display(caca_t *kk) | |||||
| line = 0; | line = 0; | ||||
| for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | for(y = 0; y < kk->drv.p->height; y += kk->drv.p->font_height) | ||||
| { | { | ||||
| uint8_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| uint32_t *attr = kk->qq->attr + line * kk->qq->width; | |||||
| uint32_t *chars = kk->qq->chars + line * kk->qq->width; | uint32_t *chars = kk->qq->chars + line * kk->qq->width; | ||||
| for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | for(x = 0; x < kk->drv.p->width; x += kk->drv.p->font_width) | ||||
| @@ -283,7 +281,7 @@ static void gl_display(caca_t *kk) | |||||
| if(c > 0x00000020 && c < 0x00000080) | if(c > 0x00000020 && c < 0x00000080) | ||||
| { | { | ||||
| glBindTexture(GL_TEXTURE_2D, kk->drv.p->id[c - 32]); | glBindTexture(GL_TEXTURE_2D, kk->drv.p->id[c - 32]); | ||||
| glColor4bv(gl_bgpal[attr[0] & 0xf]); | |||||
| glColor4bv(gl_bgpal[_cucul_rgba32_to_ansi4fg(*attr)]); | |||||
| glBegin(GL_QUADS); | glBegin(GL_QUADS); | ||||
| glTexCoord2f(0, kk->drv.p->sh); | glTexCoord2f(0, kk->drv.p->sh); | ||||
| glVertex2f(x, y); | glVertex2f(x, y); | ||||
| @@ -190,14 +190,14 @@ static unsigned int ncurses_get_window_height(caca_t *kk) | |||||
| static void ncurses_display(caca_t *kk) | static void ncurses_display(caca_t *kk) | ||||
| { | { | ||||
| int x, y; | int x, y; | ||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
| for(y = 0; y < (int)kk->qq->height; y++) | for(y = 0; y < (int)kk->qq->height; y++) | ||||
| { | { | ||||
| move(y, 0); | move(y, 0); | ||||
| for(x = kk->qq->width; x--; ) | for(x = kk->qq->width; x--; ) | ||||
| { | { | ||||
| attrset(kk->drv.p->attr[*attr++]); | |||||
| attrset(kk->drv.p->attr[_cucul_rgba32_to_ansi8(*attr++)]); | |||||
| ncurses_write_utf32(*chars++); | ncurses_write_utf32(*chars++); | ||||
| } | } | ||||
| } | } | ||||
| @@ -55,7 +55,7 @@ static unsigned int raw_get_window_height(caca_t *kk) | |||||
| static void raw_display(caca_t *kk) | static void raw_display(caca_t *kk) | ||||
| { | { | ||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
| uint32_t w, h; | uint32_t w, h; | ||||
| unsigned int n; | unsigned int n; | ||||
| @@ -70,10 +70,11 @@ static void raw_display(caca_t *kk) | |||||
| for(n = kk->qq->height * kk->qq->width; n--; ) | for(n = kk->qq->height * kk->qq->width; n--; ) | ||||
| { | { | ||||
| uint32_t c = *chars++; | uint32_t c = *chars++; | ||||
| uint8_t a = *attr++; | |||||
| uint32_t a = *attr++; | |||||
| fprintf(stdout, "%c%c%c%c%c", (c >> 24), (c >> 16) & 0xff, | |||||
| (c >> 8) & 0xff, c & 0xff, a); | |||||
| fprintf(stdout, "%c%c%c%c%c%c%c%c", | |||||
| (c >> 24), (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff, | |||||
| (a >> 24), (a >> 16) & 0xff, (a >> 8) & 0xff, a & 0xff); | |||||
| } | } | ||||
| fprintf(stdout, "ACAC"); | fprintf(stdout, "ACAC"); | ||||
| @@ -202,7 +202,7 @@ static unsigned int slang_get_window_height(caca_t *kk) | |||||
| static void slang_display(caca_t *kk) | static void slang_display(caca_t *kk) | ||||
| { | { | ||||
| int x, y; | int x, y; | ||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
| for(y = 0; y < (int)kk->qq->height; y++) | for(y = 0; y < (int)kk->qq->height; y++) | ||||
| { | { | ||||
| @@ -212,14 +212,14 @@ static void slang_display(caca_t *kk) | |||||
| uint32_t c = *chars++; | uint32_t c = *chars++; | ||||
| #if defined(OPTIMISE_SLANG_PALETTE) | #if defined(OPTIMISE_SLANG_PALETTE) | ||||
| uint8_t fgcolor = *attr & 0xf; | |||||
| uint8_t bgcolor = *attr >> 4; | |||||
| uint8_t fgcolor = _cucul_rgba32_to_ansi4fg(*attr); | |||||
| uint8_t bgcolor = _cucul_rgba32_to_ansi4bg(*attr); | |||||
| /* If foreground == background, just don't use this colour | /* If foreground == background, just don't use this colour | ||||
| * pair, and print a space instead of the real character. */ | * pair, and print a space instead of the real character. */ | ||||
| if(fgcolor != bgcolor) | if(fgcolor != bgcolor) | ||||
| { | { | ||||
| SLsmg_set_color(slang_assoc[*attr++]); | |||||
| SLsmg_set_color(slang_assoc[_cucul_rgba32_to_ansi8(*attr++)]); | |||||
| slang_write_utf32(c); | slang_write_utf32(c); | ||||
| } | } | ||||
| else | else | ||||
| @@ -236,7 +236,7 @@ static void slang_display(caca_t *kk) | |||||
| attr++; | attr++; | ||||
| } | } | ||||
| #else | #else | ||||
| SLsmg_set_color(*attr++); | |||||
| SLsmg_set_color(_cucul_rgba32_to_ansi8(*attr++)); | |||||
| slang_write_utf32(c); | slang_write_utf32(c); | ||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -116,14 +116,14 @@ static unsigned int vga_get_window_height(caca_t *kk) | |||||
| static void vga_display(caca_t *kk) | static void vga_display(caca_t *kk) | ||||
| { | { | ||||
| char *screen = (char *)(intptr_t)0x000b8000; | char *screen = (char *)(intptr_t)0x000b8000; | ||||
| uint8_t *attr = kk->qq->attr; | |||||
| uint32_t *attr = kk->qq->attr; | |||||
| uint32_t *chars = kk->qq->chars; | uint32_t *chars = kk->qq->chars; | ||||
| int n; | int n; | ||||
| for(n = kk->qq->height * kk->qq->width; n--; ) | for(n = kk->qq->height * kk->qq->width; n--; ) | ||||
| { | { | ||||
| *screen++ = _cucul_utf32_to_cp437(*chars++); | *screen++ = _cucul_utf32_to_cp437(*chars++); | ||||
| *screen++ = *attr++; | |||||
| *screen++ = _cucul_rgba32_to_ansi8(*attr++); | |||||
| } | } | ||||
| } | } | ||||
| @@ -210,8 +210,8 @@ static void win32_display(caca_t *kk) | |||||
| #endif | #endif | ||||
| kk->drv.p->buffer[i].Attributes = | kk->drv.p->buffer[i].Attributes = | ||||
| win32_fg_palette[kk->qq->attr[i] & 0xf] | |||||
| | win32_bg_palette[kk->qq->attr[i] >> 4]; | |||||
| win32_fg_palette[_cucul_rgba32_to_ansi4fg(kk->qq->attr[i])] | |||||
| | win32_bg_palette[_cucul_rgba32_to_ansi4bg(kk->qq->attr[i])]; | |||||
| } | } | ||||
| /* Blit the screen buffer */ | /* Blit the screen buffer */ | ||||
| @@ -259,15 +259,16 @@ static void x11_display(caca_t *kk) | |||||
| { | { | ||||
| for(x = 0; x < kk->qq->width; x += len) | for(x = 0; x < kk->qq->width; x += len) | ||||
| { | { | ||||
| uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| uint32_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| uint8_t bg = _cucul_rgba32_to_ansi4bg(*attr); | |||||
| len = 1; | len = 1; | ||||
| while(x + len < kk->qq->width | while(x + len < kk->qq->width | ||||
| && (attr[len] >> 4) == (attr[0] >> 4)) | |||||
| && _cucul_rgba32_to_ansi4bg(attr[len]) == bg) | |||||
| len++; | len++; | ||||
| XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, | XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, | ||||
| kk->drv.p->colors[attr[0] >> 4]); | |||||
| kk->drv.p->colors[_cucul_rgba32_to_ansi4bg(*attr)]); | |||||
| XFillRectangle(kk->drv.p->dpy, kk->drv.p->pixmap, kk->drv.p->gc, | XFillRectangle(kk->drv.p->dpy, kk->drv.p->pixmap, kk->drv.p->gc, | ||||
| x * kk->drv.p->font_width, y * kk->drv.p->font_height, | x * kk->drv.p->font_width, y * kk->drv.p->font_height, | ||||
| len * kk->drv.p->font_width, kk->drv.p->font_height); | len * kk->drv.p->font_width, kk->drv.p->font_height); | ||||
| @@ -283,14 +284,14 @@ static void x11_display(caca_t *kk) | |||||
| for(x = 0; x < kk->qq->width; x++, chars++) | for(x = 0; x < kk->qq->width; x++, chars++) | ||||
| { | { | ||||
| uint8_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| uint32_t *attr = kk->qq->attr + x + y * kk->qq->width; | |||||
| /* Skip spaces */ | /* Skip spaces */ | ||||
| if(*chars == 0x00000020) | if(*chars == 0x00000020) | ||||
| continue; | continue; | ||||
| XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, | XSetForeground(kk->drv.p->dpy, kk->drv.p->gc, | ||||
| kk->drv.p->colors[*attr & 0xf]); | |||||
| kk->drv.p->colors[_cucul_rgba32_to_ansi4fg(*attr)]); | |||||
| /* Plain ASCII, no problem. */ | /* Plain ASCII, no problem. */ | ||||
| if(*chars > 0x00000020 && *chars < 0x00000080) | if(*chars > 0x00000020 && *chars < 0x00000080) | ||||
| @@ -11,6 +11,7 @@ libcucul_la_SOURCES = \ | |||||
| canvas.c \ | canvas.c \ | ||||
| transform.c \ | transform.c \ | ||||
| charset.c \ | charset.c \ | ||||
| colour.c \ | |||||
| math.c \ | math.c \ | ||||
| line.c \ | line.c \ | ||||
| box.c \ | box.c \ | ||||
| @@ -81,7 +81,7 @@ void cucul_putchar(cucul_t *qq, int x, int y, char c) | |||||
| c = 0x20; | c = 0x20; | ||||
| qq->chars[x + y * qq->width] = c; | qq->chars[x + y * qq->width] = c; | ||||
| qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor; | |||||
| qq->attr[x + y * qq->width] = (qq->bgcolor << 16) | qq->fgcolor; | |||||
| } | } | ||||
| /** \brief Print a string. | /** \brief Print a string. | ||||
| @@ -97,8 +97,7 @@ void cucul_putchar(cucul_t *qq, int x, int y, char c) | |||||
| */ | */ | ||||
| void cucul_putstr(cucul_t *qq, int x, int y, char const *s) | void cucul_putstr(cucul_t *qq, int x, int y, char const *s) | ||||
| { | { | ||||
| uint32_t *chars; | |||||
| uint8_t *attr; | |||||
| uint32_t *chars, *attr; | |||||
| unsigned int len; | unsigned int len; | ||||
| if(y < 0 || y >= (int)qq->height || x >= (int)qq->width) | if(y < 0 || y >= (int)qq->height || x >= (int)qq->width) | ||||
| @@ -124,7 +123,7 @@ void cucul_putstr(cucul_t *qq, int x, int y, char const *s) | |||||
| while(len) | while(len) | ||||
| { | { | ||||
| *chars++ = _cucul_utf8_to_utf32(s); | *chars++ = _cucul_utf8_to_utf32(s); | ||||
| *attr++ = (qq->bgcolor << 4) | qq->fgcolor; | |||||
| *attr++ = (qq->bgcolor << 16) | qq->fgcolor; | |||||
| s = _cucul_skip_utf8(s, 1); | s = _cucul_skip_utf8(s, 1); | ||||
| len--; | len--; | ||||
| @@ -239,7 +238,7 @@ void cucul_blit(cucul_t *dst, int x, int y, | |||||
| (endi - starti) * 4); | (endi - starti) * 4); | ||||
| memcpy(dst->attr + (j + y) * dst->width + starti + x, | memcpy(dst->attr + (j + y) * dst->width + starti + x, | ||||
| src->attr + j * src->width + starti, | src->attr + j * src->width + starti, | ||||
| (endi - starti) * 1); | |||||
| (endi - starti) * 4); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -255,6 +254,6 @@ void _cucul_putchar32(cucul_t *qq, int x, int y, uint32_t c) | |||||
| return; | return; | ||||
| qq->chars[x + y * qq->width] = c; | qq->chars[x + y * qq->width] = c; | ||||
| qq->attr[x + y * qq->width] = (qq->bgcolor << 4) | qq->fgcolor; | |||||
| qq->attr[x + y * qq->width] = (qq->bgcolor << 16) | qq->fgcolor; | |||||
| } | } | ||||
| @@ -0,0 +1,45 @@ | |||||
| /* | |||||
| * libcucul Canvas for ultrafast compositing of Unicode letters | |||||
| * Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org> | |||||
| * All Rights Reserved | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the Do What The Fuck You Want To | |||||
| * Public License, Version 2, as published by Sam Hocevar. See | |||||
| * http://sam.zoy.org/wtfpl/COPYING for more details. | |||||
| */ | |||||
| /** \file colour.c | |||||
| * \version \$Id$ | |||||
| * \author Sam Hocevar <sam@zoy.org> | |||||
| * \brief Colour handling | |||||
| * | |||||
| * This file contains functions for converting colour values between | |||||
| * various colourspaces. | |||||
| */ | |||||
| #include "config.h" | |||||
| #include "cucul.h" | |||||
| #include "cucul_internals.h" | |||||
| /* FIXME: could this be inlined? */ | |||||
| uint8_t _cucul_rgba32_to_ansi8(uint32_t c) | |||||
| { | |||||
| /* FIXME: we need nearest colour handling for non-ANSI */ | |||||
| return (c & 0x0000000f) | ((c & 0x000f0000) >> 12); | |||||
| } | |||||
| uint8_t _cucul_rgba32_to_ansi4fg(uint32_t c) | |||||
| { | |||||
| /* FIXME: we need nearest colour handling for non-ANSI */ | |||||
| return c & 0x0000000f; | |||||
| } | |||||
| uint8_t _cucul_rgba32_to_ansi4bg(uint32_t c) | |||||
| { | |||||
| /* FIXME: we need nearest colour handling for non-ANSI */ | |||||
| return (c & 0x000f0000) >> 16; | |||||
| } | |||||
| @@ -21,6 +21,7 @@ | |||||
| #include "config.h" | #include "config.h" | ||||
| #if !defined(__KERNEL__) | #if !defined(__KERNEL__) | ||||
| # include <stdio.h> | |||||
| # include <stdlib.h> | # include <stdlib.h> | ||||
| # include <string.h> | # include <string.h> | ||||
| #endif | #endif | ||||
| @@ -93,7 +94,7 @@ cucul_t *cucul_load(void *data, unsigned int size) | |||||
| if(!width || !height) | if(!width || !height) | ||||
| return NULL; | return NULL; | ||||
| if(size != 12 + width * height * 5 + 4) | |||||
| if(size != 12 + width * height * 8 + 4) | |||||
| return NULL; | return NULL; | ||||
| if(buf[size - 4] != 'A' || buf[size - 3] != 'C' | if(buf[size - 4] != 'A' || buf[size - 3] != 'C' | ||||
| @@ -107,11 +108,14 @@ cucul_t *cucul_load(void *data, unsigned int size) | |||||
| for(n = height * width; n--; ) | for(n = height * width; n--; ) | ||||
| { | { | ||||
| qq->chars[n] = ((uint32_t)buf[12 + 5 * n] << 24) | |||||
| | ((uint32_t)buf[13 + 5 * n] << 16) | |||||
| | ((uint32_t)buf[14 + 5 * n] << 8) | |||||
| | (uint32_t)buf[15 + 5 * n]; | |||||
| qq->attr[n] = buf[16 + 5 * n]; | |||||
| qq->chars[n] = ((uint32_t)buf[12 + 8 * n] << 24) | |||||
| | ((uint32_t)buf[13 + 8 * n] << 16) | |||||
| | ((uint32_t)buf[14 + 8 * n] << 8) | |||||
| | (uint32_t)buf[15 + 8 * n]; | |||||
| qq->attr[n] = ((uint32_t)buf[16 + 8 * n] << 24) | |||||
| | ((uint32_t)buf[17 + 8 * n] << 16) | |||||
| | ((uint32_t)buf[18 + 8 * n] << 8) | |||||
| | (uint32_t)buf[19 + 8 * n]; | |||||
| } | } | ||||
| return qq; | return qq; | ||||
| @@ -299,7 +303,7 @@ void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) | |||||
| if(new_size > old_size) | if(new_size > old_size) | ||||
| { | { | ||||
| qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t)); | qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t)); | ||||
| qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t)); | |||||
| qq->attr = realloc(qq->attr, new_size * sizeof(uint32_t)); | |||||
| } | } | ||||
| /* Step 2: move line data if necessary. */ | /* Step 2: move line data if necessary. */ | ||||
| @@ -325,7 +329,7 @@ void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) | |||||
| for(x = width - old_width; x--; ) | for(x = width - old_width; x--; ) | ||||
| qq->chars[y * width + old_width + x] = (uint32_t)' '; | qq->chars[y * width + old_width + x] = (uint32_t)' '; | ||||
| memset(qq->attr + y * width + old_width, 0, | memset(qq->attr + y * width + old_width, 0, | ||||
| width - old_width); | |||||
| (width - old_width) * 4); | |||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| @@ -351,14 +355,14 @@ void _cucul_set_size(cucul_t *qq, unsigned int width, unsigned int height) | |||||
| for(x = (height - old_height) * width; x--; ) | for(x = (height - old_height) * width; x--; ) | ||||
| qq->chars[old_height * width + x] = (uint32_t)' '; | qq->chars[old_height * width + x] = (uint32_t)' '; | ||||
| memset(qq->attr + old_height * width, 0, | memset(qq->attr + old_height * width, 0, | ||||
| (height - old_height) * width); | |||||
| (height - old_height) * width * 4); | |||||
| } | } | ||||
| /* Step 4: if new area is smaller, resize memory area now. */ | /* Step 4: if new area is smaller, resize memory area now. */ | ||||
| if(new_size <= old_size) | if(new_size <= old_size) | ||||
| { | { | ||||
| qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t)); | qq->chars = realloc(qq->chars, new_size * sizeof(uint32_t)); | ||||
| qq->attr = realloc(qq->attr, new_size * sizeof(uint8_t)); | |||||
| qq->attr = realloc(qq->attr, new_size * sizeof(uint32_t)); | |||||
| } | } | ||||
| /* Recompute the scratch line and the empty line */ | /* Recompute the scratch line and the empty line */ | ||||
| @@ -37,7 +37,7 @@ struct cucul_context | |||||
| unsigned int width, height; | unsigned int width, height; | ||||
| uint32_t *chars; | uint32_t *chars; | ||||
| uint8_t *attr; | |||||
| uint32_t *attr; | |||||
| char *empty_line, *scratch_line; | char *empty_line, *scratch_line; | ||||
| enum cucul_color fgcolor; | enum cucul_color fgcolor; | ||||
| @@ -61,6 +61,11 @@ extern uint32_t _cucul_utf8_to_utf32(char const *); | |||||
| extern uint8_t _cucul_utf32_to_cp437(uint32_t); | extern uint8_t _cucul_utf32_to_cp437(uint32_t); | ||||
| extern uint32_t _cucul_cp437_to_utf32(uint8_t); | extern uint32_t _cucul_cp437_to_utf32(uint8_t); | ||||
| /* Colour functions */ | |||||
| uint8_t _cucul_rgba32_to_ansi8(uint32_t); | |||||
| uint8_t _cucul_rgba32_to_ansi4fg(uint32_t); | |||||
| uint8_t _cucul_rgba32_to_ansi4bg(uint32_t); | |||||
| /* Export functions */ | /* Export functions */ | ||||
| extern void _cucul_get_ansi(cucul_t *, struct cucul_export *); | extern void _cucul_get_ansi(cucul_t *, struct cucul_export *); | ||||
| extern void _cucul_get_html(cucul_t *, struct cucul_export *); | extern void _cucul_get_html(cucul_t *, struct cucul_export *); | ||||
| @@ -58,7 +58,7 @@ void _cucul_get_ansi(cucul_t *qq, struct cucul_export *ex) | |||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *linechar = qq->chars + y * qq->width; | uint32_t *linechar = qq->chars + y * qq->width; | ||||
| uint8_t prevfg = -1; | uint8_t prevfg = -1; | ||||
| @@ -66,8 +66,8 @@ void _cucul_get_ansi(cucul_t *qq, struct cucul_export *ex) | |||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| { | { | ||||
| uint8_t fg = palette[lineattr[x] & 0x0f]; | |||||
| uint8_t bg = palette[lineattr[x] >> 4]; | |||||
| uint8_t fg = _cucul_rgba32_to_ansi4fg(lineattr[x]); | |||||
| uint8_t bg = _cucul_rgba32_to_ansi4bg(lineattr[x]); | |||||
| uint32_t c = linechar[x]; | uint32_t c = linechar[x]; | ||||
| if(fg != prevfg || bg != prevbg) | if(fg != prevfg || bg != prevbg) | ||||
| @@ -72,12 +72,13 @@ void _cucul_get_html(cucul_t *qq, struct cucul_export *ex) | |||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *linechar = qq->chars + y * qq->width; | uint32_t *linechar = qq->chars + y * qq->width; | ||||
| for(x = 0; x < qq->width; x += len) | for(x = 0; x < qq->width; x += len) | ||||
| { | { | ||||
| cur += sprintf(cur, "<span class='b%02x'>", lineattr[x]); | |||||
| cur += sprintf(cur, "<span class='b%02x'>", | |||||
| _cucul_rgba32_to_ansi8(lineattr[x])); | |||||
| for(len = 0; | for(len = 0; | ||||
| x + len < qq->width && lineattr[x + len] == lineattr[x]; | x + len < qq->width && lineattr[x + len] == lineattr[x]; | ||||
| @@ -141,7 +142,7 @@ void _cucul_get_html3(cucul_t *qq, struct cucul_export *ex) | |||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *linechar = qq->chars + y * qq->width; | uint32_t *linechar = qq->chars + y * qq->width; | ||||
| cur += sprintf(cur, "<tr>"); | cur += sprintf(cur, "<tr>"); | ||||
| @@ -156,13 +157,14 @@ void _cucul_get_html3(cucul_t *qq, struct cucul_export *ex) | |||||
| while(x + len < qq->width && lineattr[x + len] == lineattr[x]) | while(x + len < qq->width && lineattr[x + len] == lineattr[x]) | ||||
| len++; | len++; | ||||
| cur += sprintf(cur, "<td bgcolor=#%06x", palette[lineattr[x] >> 4]); | |||||
| cur += sprintf(cur, "<td bgcolor=#%06x", | |||||
| _cucul_rgba32_to_ansi4bg(lineattr[x])); | |||||
| if(len > 1) | if(len > 1) | ||||
| cur += sprintf(cur, " colspan=%d", len); | cur += sprintf(cur, " colspan=%d", len); | ||||
| cur += sprintf(cur, "><font color=#%06x>", | cur += sprintf(cur, "><font color=#%06x>", | ||||
| palette[lineattr[x] & 0x0f]); | |||||
| _cucul_rgba32_to_ansi4fg(lineattr[x])); | |||||
| for(i = 0; i < len; i++) | for(i = 0; i < len; i++) | ||||
| { | { | ||||
| @@ -62,7 +62,7 @@ void _cucul_get_irc(cucul_t *qq, struct cucul_export *ex) | |||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *linechar = qq->chars + y * qq->width; | uint32_t *linechar = qq->chars + y * qq->width; | ||||
| uint8_t prevfg = -1; | uint8_t prevfg = -1; | ||||
| @@ -70,8 +70,8 @@ void _cucul_get_irc(cucul_t *qq, struct cucul_export *ex) | |||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| { | { | ||||
| uint8_t fg = palette[lineattr[x] & 0x0f]; | |||||
| uint8_t bg = palette[lineattr[x] >> 4]; | |||||
| uint8_t fg = palette[_cucul_rgba32_to_ansi4fg(lineattr[x])]; | |||||
| uint8_t bg = palette[_cucul_rgba32_to_ansi4bg(lineattr[x])]; | |||||
| uint32_t c = linechar[x]; | uint32_t c = linechar[x]; | ||||
| if(bg == prevbg) | if(bg == prevbg) | ||||
| @@ -85,12 +85,12 @@ void _cucul_get_ps(cucul_t *qq, struct cucul_export *ex) | |||||
| /* Background, drawn using csquare macro defined in header */ | /* Background, drawn using csquare macro defined in header */ | ||||
| for(y = qq->height; y--; ) | for(y = qq->height; y--; ) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| { | { | ||||
| cur += sprintf(cur, "1 0 translate\n %s csquare\n", | cur += sprintf(cur, "1 0 translate\n %s csquare\n", | ||||
| palette[*lineattr++ >> 4]); | |||||
| _cucul_rgba32_to_ansi4bg(*lineattr++)); | |||||
| } | } | ||||
| /* Return to beginning of the line, and jump to the next one */ | /* Return to beginning of the line, and jump to the next one */ | ||||
| @@ -101,7 +101,7 @@ void _cucul_get_ps(cucul_t *qq, struct cucul_export *ex) | |||||
| for(y = qq->height; y--; ) | for(y = qq->height; y--; ) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + (qq->height - y - 1) * qq->width; | |||||
| uint32_t *lineattr = qq->attr + (qq->height - y - 1) * qq->width; | |||||
| uint32_t *linechar = qq->chars + (qq->height - y - 1) * qq->width; | uint32_t *linechar = qq->chars + (qq->height - y - 1) * qq->width; | ||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| @@ -111,7 +111,7 @@ void _cucul_get_ps(cucul_t *qq, struct cucul_export *ex) | |||||
| cur += sprintf(cur, "newpath\n"); | cur += sprintf(cur, "newpath\n"); | ||||
| cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10); | cur += sprintf(cur, "%d %d moveto\n", (x + 1) * 6, y * 10); | ||||
| cur += sprintf(cur, "%s setrgbcolor\n", | cur += sprintf(cur, "%s setrgbcolor\n", | ||||
| palette[*lineattr++ & 0x0f]); | |||||
| _cucul_rgba32_to_ansi4fg(*lineattr++)); | |||||
| if(c < 0x00000020) | if(c < 0x00000020) | ||||
| cur += sprintf(cur, "(?) show\n"); | cur += sprintf(cur, "(?) show\n"); | ||||
| @@ -82,20 +82,21 @@ void _cucul_get_svg(cucul_t *qq, struct cucul_export *ex) | |||||
| /* Background */ | /* Background */ | ||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| { | { | ||||
| cur += sprintf(cur, "<rect class=\"b%02x\" x=\"%d\" y=\"%d\"" | cur += sprintf(cur, "<rect class=\"b%02x\" x=\"%d\" y=\"%d\"" | ||||
| " width=\"6\" height=\"10\"/>\n", | " width=\"6\" height=\"10\"/>\n", | ||||
| *lineattr++, x * 6, y * 10); | |||||
| _cucul_rgba32_to_ansi8(*lineattr++), | |||||
| x * 6, y * 10); | |||||
| } | } | ||||
| } | } | ||||
| /* Text */ | /* Text */ | ||||
| for(y = 0; y < qq->height; y++) | for(y = 0; y < qq->height; y++) | ||||
| { | { | ||||
| uint8_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *lineattr = qq->attr + y * qq->width; | |||||
| uint32_t *linechar = qq->chars + y * qq->width; | uint32_t *linechar = qq->chars + y * qq->width; | ||||
| for(x = 0; x < qq->width; x++) | for(x = 0; x < qq->width; x++) | ||||
| @@ -103,7 +104,8 @@ void _cucul_get_svg(cucul_t *qq, struct cucul_export *ex) | |||||
| uint32_t c = *linechar++; | uint32_t c = *linechar++; | ||||
| cur += sprintf(cur, "<text class=\"f%02x\" x=\"%d\" y=\"%d\">", | cur += sprintf(cur, "<text class=\"f%02x\" x=\"%d\" y=\"%d\">", | ||||
| *lineattr++, x * 6, (y * 10) + 10); | |||||
| _cucul_rgba32_to_ansi8(*lineattr++), | |||||
| x * 6, (y * 10) + 10); | |||||
| if(c < 0x00000020) | if(c < 0x00000020) | ||||
| cur += sprintf(cur, "?"); | cur += sprintf(cur, "?"); | ||||
| else if(c > 0x0000007f) | else if(c > 0x0000007f) | ||||
| @@ -38,12 +38,12 @@ static uint32_t rotatechar(uint32_t ch); | |||||
| */ | */ | ||||
| void cucul_invert(cucul_t *qq) | void cucul_invert(cucul_t *qq) | ||||
| { | { | ||||
| uint8_t *attr = qq->attr; | |||||
| uint32_t *attr = qq->attr; | |||||
| unsigned int i; | unsigned int i; | ||||
| for(i = qq->height * qq->width; i--; ) | for(i = qq->height * qq->width; i--; ) | ||||
| { | { | ||||
| *attr = ~*attr; | |||||
| *attr = *attr ^ 0x000f000f; | |||||
| attr++; | attr++; | ||||
| } | } | ||||
| } | } | ||||
| @@ -63,13 +63,13 @@ void cucul_flip(cucul_t *qq) | |||||
| { | { | ||||
| uint32_t *cleft = qq->chars + y * qq->width; | uint32_t *cleft = qq->chars + y * qq->width; | ||||
| uint32_t *cright = cleft + qq->width - 1; | uint32_t *cright = cleft + qq->width - 1; | ||||
| uint8_t *aleft = qq->attr + y * qq->width; | |||||
| uint8_t *aright = aleft + qq->width - 1; | |||||
| uint32_t *aleft = qq->attr + y * qq->width; | |||||
| uint32_t *aright = aleft + qq->width - 1; | |||||
| while(cleft < cright) | while(cleft < cright) | ||||
| { | { | ||||
| uint32_t ch; | uint32_t ch; | ||||
| uint8_t attr; | |||||
| uint32_t attr; | |||||
| /* Swap attributes */ | /* Swap attributes */ | ||||
| attr = *aright; *aright = *aleft; *aleft = attr; | attr = *aright; *aright = *aleft; *aleft = attr; | ||||
| @@ -100,13 +100,13 @@ void cucul_flop(cucul_t *qq) | |||||
| { | { | ||||
| uint32_t *ctop = qq->chars + x; | uint32_t *ctop = qq->chars + x; | ||||
| uint32_t *cbottom = ctop + qq->width * (qq->height - 1); | uint32_t *cbottom = ctop + qq->width * (qq->height - 1); | ||||
| uint8_t *atop = qq->attr + x; | |||||
| uint8_t *abottom = atop + qq->width * (qq->height - 1); | |||||
| uint32_t *atop = qq->attr + x; | |||||
| uint32_t *abottom = atop + qq->width * (qq->height - 1); | |||||
| while(ctop < cbottom) | while(ctop < cbottom) | ||||
| { | { | ||||
| uint32_t ch; | uint32_t ch; | ||||
| uint8_t attr; | |||||
| uint32_t attr; | |||||
| /* Swap attributes */ | /* Swap attributes */ | ||||
| attr = *abottom; *abottom = *atop; *atop = attr; | attr = *abottom; *abottom = *atop; *atop = attr; | ||||
| @@ -135,13 +135,13 @@ void cucul_rotate(cucul_t *qq) | |||||
| { | { | ||||
| uint32_t *cbegin = qq->chars; | uint32_t *cbegin = qq->chars; | ||||
| uint32_t *cend = cbegin + qq->width * qq->height - 1; | uint32_t *cend = cbegin + qq->width * qq->height - 1; | ||||
| uint8_t *abegin = qq->attr; | |||||
| uint8_t *aend = abegin + qq->width * qq->height - 1; | |||||
| uint32_t *abegin = qq->attr; | |||||
| uint32_t *aend = abegin + qq->width * qq->height - 1; | |||||
| while(cbegin < cend) | while(cbegin < cend) | ||||
| { | { | ||||
| uint32_t ch; | uint32_t ch; | ||||
| uint8_t attr; | |||||
| uint32_t attr; | |||||
| /* Swap attributes */ | /* Swap attributes */ | ||||
| attr = *aend; *aend = *abegin; *abegin = attr; | attr = *aend; *aend = *abegin; *abegin = attr; | ||||
| @@ -214,7 +214,7 @@ int main(void) | |||||
| height = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16) | height = ((uint32_t)buf[8] << 24) | ((uint32_t)buf[9] << 16) | ||||
| | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11]; | | ((uint32_t)buf[10] << 8) | (uint32_t)buf[11]; | ||||
| size = 12 + width * height * 5 + 4; | |||||
| size = 12 + width * height * 8 + 4; | |||||
| buf = server->input = realloc(server->input, size); | buf = server->input = realloc(server->input, size); | ||||
| read(0, buf + 12, size - 12); | read(0, buf + 12, size - 12); | ||||