mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-26 03:23:46 +08:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42b28fcc59 | ||
|
|
2bde8e299a | ||
|
|
08d4ab78e5 | ||
|
|
0cda03a2eb | ||
|
|
4cf4d204e7 | ||
|
|
6aa294e75b | ||
|
|
7718be5200 | ||
|
|
78e6d6581e | ||
|
|
62b3dc11d0 | ||
|
|
67cddafa19 |
@@ -10,6 +10,7 @@ Makefile
|
||||
Makefile.in
|
||||
.deps/
|
||||
.libs/
|
||||
m4/*.m4
|
||||
/acinclude.m4
|
||||
/aclocal.m4
|
||||
/autom4te.cache
|
||||
@@ -21,6 +22,7 @@ Makefile.in
|
||||
/depcomp
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/*.pc
|
||||
/*config.h
|
||||
/*config.h.in
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = src 3rd-party include rtos etc m4 cmake build
|
||||
|
||||
EXTRA_DIST = minigui.pc.in \
|
||||
|
||||
@@ -566,7 +566,7 @@ A brief history description of the development progress is listed as follow:
|
||||
1. Jan., 2022: FMSoft released MiniGUI version 5.0.9.
|
||||
1. Sep., 2022: FMSoft released MiniGUI version 5.0.10.
|
||||
1. Aug., 2023: FMSoft released MiniGUI version 5.0.13.
|
||||
1. May., 2025: FMSoft released MiniGUI version 5.0.15.
|
||||
1. May., 2025: FMSoft released MiniGUI version 5.0.16.
|
||||
|
||||
## AUTHORS AND COPYING
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Release Notes
|
||||
|
||||
- [Version 5.0.16](#version-5016)
|
||||
+ [What's new in version 5.0.16](#whats-new-in-version-5016)
|
||||
- [Version 5.0.15](#version-5015)
|
||||
+ [What's new in version 5.0.15](#whats-new-in-version-5015)
|
||||
- [Version 5.0.13](#version-5013)
|
||||
@@ -34,6 +36,19 @@
|
||||
+ [Changes leading to incompatibility](#changes-leading-to-incompatibility)
|
||||
+ [Deprecated APIs](#deprecated-apis)
|
||||
|
||||
## Version 5.0.16
|
||||
|
||||
On May 27, 2025, FMSoft announces the availability of MiniGUI 5.0.16,
|
||||
which is a bugfix release with some minor enhancements of MiniGUI 5.0.x.
|
||||
|
||||
* BUGFIXING:
|
||||
- The desktop thread can not handle the request from other threads as soon as possible.
|
||||
- The `MSG_TIMEOUT` message can not be fired correctly under MiniGUI-Threads mode.
|
||||
- Bad subpixel rendering when background color is RGBA0000.
|
||||
* TUNING:
|
||||
- Tune `configure.ac` and `Makefile.am` to use the system libtool scripts.
|
||||
- Do not check `pciaccess` if the target architecture is not `i386`.
|
||||
|
||||
## Version 5.0.15
|
||||
|
||||
On May 09, 2025, FMSoft announces the availability of MiniGUI 5.0.15,
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Version 5.0.15 (2025/05/09)
|
||||
Version 5.0.16 (2025/05/27)
|
||||
|
||||
This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version.
|
||||
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
cat m4/*.m4 > acinclude.m4
|
||||
libtoolize
|
||||
cat m4/*.m4 > aclocal.m4
|
||||
aclocal
|
||||
autoheader
|
||||
automake --add-missing --foreign --copy
|
||||
|
||||
+30
-28
@@ -1,7 +1,8 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(libminigui, 5.0.15)
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([libminigui],[5.0.16])
|
||||
AC_CONFIG_SRCDIR(src/main/main.c)
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
|
||||
dnl Set various version strings - taken gratefully from the SDL sources
|
||||
#
|
||||
@@ -16,9 +17,9 @@ dnl Set various version strings - taken gratefully from the SDL sources
|
||||
#
|
||||
MINIGUI_MAJOR_VERSION=5
|
||||
MINIGUI_MINOR_VERSION=0
|
||||
MINIGUI_MICRO_VERSION=15
|
||||
MINIGUI_INTERFACE_AGE=0
|
||||
MINIGUI_BINARY_AGE=0
|
||||
MINIGUI_MICRO_VERSION=16
|
||||
MINIGUI_INTERFACE_AGE=1
|
||||
MINIGUI_BINARY_AGE=1
|
||||
MINIGUI_VERSION=$MINIGUI_MAJOR_VERSION.$MINIGUI_MINOR_VERSION.$MINIGUI_MICRO_VERSION
|
||||
|
||||
AC_SUBST(MINIGUI_MAJOR_VERSION)
|
||||
@@ -40,27 +41,24 @@ AC_SUBST(LT_CURRENT)
|
||||
AC_SUBST(LT_REVISION)
|
||||
AC_SUBST(LT_AGE)
|
||||
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_CANONICAL_TARGET
|
||||
|
||||
dnl ========================================================================
|
||||
dnl Init automake
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_CONFIG_HEADER(mgconfig.h)
|
||||
AC_CONFIG_HEADERS([mgconfig.h])
|
||||
|
||||
dnl ========================================================================
|
||||
dnl Check for tools
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PROG_CC
|
||||
AC_PROG_LD
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
LT_INIT
|
||||
|
||||
dnl ========================================================================
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_DIRENT
|
||||
AC_CHECK_HEADERS(limits.h math.h stdatomic.h locale.h unistd.h termio.h sys/types.h sys/time.h sys/select.h sys/memfd.h)
|
||||
|
||||
@@ -68,7 +66,6 @@ dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
AC_HEADER_TIME
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for library functions.
|
||||
@@ -884,14 +881,14 @@ CheckFBCON()
|
||||
if test "x$enable_video_fbcon" = "xyes"; then
|
||||
AC_MSG_CHECKING(for FrameBuffer console support)
|
||||
video_fbcon=no
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <linux/fb.h>
|
||||
#include <linux/kd.h>
|
||||
#include <linux/keyboard.h>
|
||||
],[
|
||||
],[
|
||||
]], [[
|
||||
]])],[
|
||||
video_fbcon=yes
|
||||
])
|
||||
],[])
|
||||
AC_MSG_RESULT($video_fbcon)
|
||||
if test "x$video_fbcon" = "xyes"; then
|
||||
AC_DEFINE(_MGGAL_FBCON, 1,
|
||||
@@ -899,9 +896,13 @@ CheckFBCON()
|
||||
VIDEO_SUBDIRS="$VIDEO_SUBDIRS fbcon"
|
||||
VIDEO_DRIVERS="$VIDEO_DRIVERS fbcon/libvideo_fbcon.la"
|
||||
|
||||
have_pciaccess="yes"
|
||||
AC_CHECK_LIB(pciaccess, pci_system_init,
|
||||
DEP_LIBS="$DEP_LIBS -lpciaccess", have_pciaccess="no")
|
||||
if test "x$target_cpu" = "xi386"; then
|
||||
have_pciaccess="yes"
|
||||
AC_CHECK_LIB(pciaccess, pci_system_init,
|
||||
DEP_LIBS="$DEP_LIBS -lpciaccess", have_pciaccess="no")
|
||||
else
|
||||
have_pciaccess="no"
|
||||
fi
|
||||
|
||||
if test "x$have_pciaccess" = "xyes"; then
|
||||
AC_DEFINE(_MGHAVE_PCIACCESS, 1,
|
||||
@@ -1170,12 +1171,12 @@ CheckDirectFBVideo()
|
||||
if test "x$enable_video_dfb" = "xyes"; then
|
||||
AC_MSG_CHECKING(for DirectFB support)
|
||||
video_dfb=no
|
||||
AC_TRY_COMPILE([
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <directfb.h>
|
||||
],[
|
||||
],[
|
||||
]], [[
|
||||
]])],[
|
||||
video_dfb=yes
|
||||
])
|
||||
],[])
|
||||
AC_MSG_RESULT($video_dfb)
|
||||
if test "x$video_dfb" = "xyes"; then
|
||||
AC_DEFINE(_MGGAL_DFB, 1,
|
||||
@@ -2641,7 +2642,7 @@ if test "x$devel_mode" = "xyes"; then
|
||||
CPPFLAGS="$CPPFLAGS -D_DEBUG"
|
||||
fi
|
||||
|
||||
if test "$ac_cv_prog_gcc" = "yes"; then
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes"; then
|
||||
CFLAGS="$CFLAGS -Wall -Werror"
|
||||
fi
|
||||
|
||||
@@ -2651,7 +2652,7 @@ else
|
||||
CPPFLAGS="$CPPFLAGS -DNDEBUG"
|
||||
fi
|
||||
|
||||
if test "$ac_cv_prog_gcc" = "yes"; then
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes"; then
|
||||
CFLAGS="$CFLAGS -fmax-errors=10 -Wstrict-prototypes -pipe"
|
||||
fi
|
||||
|
||||
@@ -2688,8 +2689,7 @@ AM_CONDITIONAL(MGLIB_MVFB, test "x$with_libsuffix" = "xmvfb")
|
||||
AM_CONDITIONAL(MG_ENABLE_SPLASH, test "x$build_splash" = "xyes")
|
||||
AM_CONDITIONAL(MG_ENABLE_SCREENSAVER, test "x$build_screensaver" = "xyes")
|
||||
|
||||
AC_OUTPUT(
|
||||
minigui.pc
|
||||
AC_CONFIG_FILES([minigui.pc
|
||||
Makefile
|
||||
cmake/Makefile
|
||||
src/Makefile
|
||||
@@ -2756,7 +2756,8 @@ etc/Makefile
|
||||
3rd-party/scripteasy/Makefile
|
||||
m4/Makefile
|
||||
build/Makefile
|
||||
)
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
CCVERSION=`$CC --version | head -n 1`
|
||||
|
||||
@@ -2765,6 +2766,7 @@ AC_MSG_NOTICE([
|
||||
# Main building configuration:
|
||||
|
||||
## Global Features:
|
||||
* Architecture: ${target_cpu}
|
||||
* Operating system: ${osname}
|
||||
* Runtime mode: ${runtime_mode}
|
||||
* Virtual Window: ${virtual_window}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# This file does not do anything, except making sure these files are included
|
||||
# when you run 'make dist'.
|
||||
|
||||
EXTRA_DIST = libtool.m4
|
||||
EXTRA_DIST =
|
||||
|
||||
Vendored
-3724
File diff suppressed because it is too large
Load Diff
@@ -166,7 +166,7 @@ static unsigned short iso8859_68x_unicode_map [] =
|
||||
0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, /*0xF1~0xF4*/
|
||||
0xFECB, 0xFECF, 0xFED3, 0xFED7, /*0xF5~0xF8*/
|
||||
0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, /*0xF9~0xFC*/
|
||||
0xFEEB, 0xFEF4, 0xFFFF, /*0xFD~0xFF*/
|
||||
0xFEEB, 0xFEF3, 0xFFFF, /*0xFD~0xFF*/
|
||||
|
||||
0xFEC4, 0xFEC6, 0xFE82, 0xFE84, /*0x100~0x103*/
|
||||
0xFE86, 0xFE88, 0xFE8C, 0xFE8E, /*0x104~0x107*/
|
||||
@@ -576,7 +576,7 @@ static BidiType __mg_iso8859_6_bidi_char_type_map[] = {
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_ON,
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||
|
||||
/*0xf0~0xff*/
|
||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||
|
||||
+110
-9
@@ -286,7 +286,7 @@ static TYPERUN* get_runtype_link (const CHARSETOPS* charset_ops, Achar32* achars
|
||||
last = list;
|
||||
|
||||
for (i = 0; i < len; i++){
|
||||
if ((type = charset_ops->bidi_char_type (achars[i])) != last->type){
|
||||
if ((type = charset_ops->bidi_char_type (REAL_ACHAR(achars[i]))) != last->type){
|
||||
link = calloc(1, sizeof(TYPERUN));
|
||||
link->type = type;
|
||||
link->pos = i;
|
||||
@@ -456,7 +456,7 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
|
||||
prev_type_org = TYPE(pp);
|
||||
}
|
||||
|
||||
compact_neutrals (type_rl_list);
|
||||
compact_list (type_rl_list);
|
||||
|
||||
#ifdef BIDI_DEBUG
|
||||
print_run_types(type_rl_list);
|
||||
@@ -469,19 +469,115 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
|
||||
#define BIDI_EMBEDDING_DIR(list) BIDI_LEVEL_TO_DIR(LEVEL(list))
|
||||
|
||||
/* 4.Resolving Neutral Types */
|
||||
static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir)
|
||||
static void bidi_resolveNeutrals(const CHARSETOPS* charset_ops, Achar32* achars, int len,
|
||||
TYPERUN **ptype_rl_list, Uint32 base_bir)
|
||||
{
|
||||
TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL;
|
||||
Uint32* bracket_types = NULL;
|
||||
int i;
|
||||
|
||||
if (charset_ops->bidi_mirror_char && achars && len > 0) {
|
||||
typedef struct {
|
||||
int pos;
|
||||
Achar32 mirror;
|
||||
} BRSTACK;
|
||||
|
||||
BRSTACK* stack = NULL;
|
||||
int top = 0;
|
||||
|
||||
bracket_types = calloc(len, sizeof(Uint32));
|
||||
stack = calloc(len, sizeof(BRSTACK));
|
||||
|
||||
if (bracket_types && stack) {
|
||||
for (i = 0; i < len; i++) {
|
||||
Achar32 ch = REAL_ACHAR(achars[i]);
|
||||
Achar32 mirrored;
|
||||
if (!charset_ops->bidi_mirror_char(ch, &mirrored))
|
||||
continue;
|
||||
|
||||
if (ch < mirrored) {
|
||||
stack[top].pos = i;
|
||||
stack[top].mirror = mirrored;
|
||||
top++;
|
||||
}
|
||||
else {
|
||||
if (top > 0 && stack[top - 1].mirror == ch) {
|
||||
int open_pos = stack[top - 1].pos;
|
||||
int close_pos = i;
|
||||
Uint32 found_dir = BIDI_TYPE_ON;
|
||||
int k;
|
||||
|
||||
for (k = open_pos + 1; k < close_pos; k++) {
|
||||
Uint32 t = charset_ops->bidi_char_type(REAL_ACHAR(achars[k]));
|
||||
if (t == BIDI_TYPE_AL)
|
||||
t = BIDI_TYPE_RTL;
|
||||
if (BIDI_IS_LETTER(t)) {
|
||||
found_dir = BIDI_IS_RTL(t) ? BIDI_TYPE_RTL : BIDI_TYPE_LTR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found_dir != BIDI_TYPE_ON) {
|
||||
bracket_types[open_pos] = found_dir;
|
||||
bracket_types[close_pos] = found_dir;
|
||||
}
|
||||
|
||||
top--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stack)
|
||||
free(stack);
|
||||
}
|
||||
|
||||
if (bracket_types) {
|
||||
for (pp = type_rl_list->next; pp->next; pp = pp->next) {
|
||||
if (BIDI_IS_NEUTRAL(TYPE(pp))) {
|
||||
int start = POS(pp);
|
||||
int end = start + LEN(pp);
|
||||
Uint32 forced = BIDI_TYPE_ON;
|
||||
|
||||
if (end > len)
|
||||
end = len;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
if (bracket_types[i] == BIDI_TYPE_RTL) {
|
||||
forced = BIDI_TYPE_RTL;
|
||||
break;
|
||||
}
|
||||
if (bracket_types[i] == BIDI_TYPE_LTR) {
|
||||
forced = BIDI_TYPE_LTR;
|
||||
}
|
||||
}
|
||||
|
||||
if (forced != BIDI_TYPE_ON) {
|
||||
TYPE(pp) = forced;
|
||||
}
|
||||
}
|
||||
}
|
||||
compact_list (type_rl_list);
|
||||
}
|
||||
|
||||
DBGLOG ("\n4.Resolving neutral types\n");
|
||||
|
||||
for (pp = type_rl_list->next; pp->next; pp = pp->next)
|
||||
{
|
||||
Uint32 prev_type, this_type, next_type;
|
||||
TYPERUN* prev = NULL;
|
||||
TYPERUN* next = NULL;
|
||||
|
||||
prev = pp->prev;
|
||||
while (prev && BIDI_IS_NEUTRAL(TYPE(prev)) && !BIDI_IS_SENTINEL(TYPE(prev)))
|
||||
prev = prev->prev;
|
||||
prev_type = (!prev || BIDI_IS_SENTINEL(TYPE(prev))) ? base_bir : TYPE(prev);
|
||||
|
||||
prev_type = TYPE(pp->prev);
|
||||
this_type = TYPE(pp);
|
||||
next_type = (pp->next) ? TYPE(pp->next) : this_type;
|
||||
next = pp->next;
|
||||
while (next && BIDI_IS_NEUTRAL(TYPE(next)) && !BIDI_IS_SENTINEL(TYPE(next)))
|
||||
next = next->next;
|
||||
next_type = (!next || BIDI_IS_SENTINEL(TYPE(next))) ? base_bir : TYPE(next);
|
||||
/* "European and arabic numbers are treated as though they were R, NUMBER_TO_RTL does this. */
|
||||
this_type = BIDI_NUMBER_TO_RTL(this_type);
|
||||
prev_type = BIDI_NUMBER_TO_RTL(prev_type);
|
||||
@@ -498,6 +594,9 @@ static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir)
|
||||
print_resolved_levels (type_rl_list);
|
||||
print_resolved_types (type_rl_list);
|
||||
#endif
|
||||
|
||||
if (bracket_types)
|
||||
free(bracket_types);
|
||||
}
|
||||
|
||||
/* 5.Resolving implicit levels. */
|
||||
@@ -549,10 +648,13 @@ bidi_resolveMirrorChar (const CHARSETOPS* charset_ops, Achar32* achars, int len,
|
||||
int i;
|
||||
for (i = POS (pp); i < POS (pp) + LEN (pp); i++)
|
||||
{
|
||||
Achar32 ch = achars[i];
|
||||
Achar32 real_ch = REAL_ACHAR(ch);
|
||||
Achar32 mirrored_ch;
|
||||
if (charset_ops->bidi_mirror_char &&
|
||||
charset_ops->bidi_mirror_char (achars[i], &mirrored_ch))
|
||||
achars[i] = mirrored_ch;
|
||||
charset_ops->bidi_mirror_char (real_ch, &mirrored_ch)) {
|
||||
achars[i] = IS_MBCHV(ch) ? SET_MBCHV(mirrored_ch) : mirrored_ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -593,7 +695,7 @@ static void bidi_resolve_string (const CHARSETOPS* charset_ops,
|
||||
bidi_resolveWeak(&type_rl_list, base_dir);
|
||||
|
||||
/* 4.Resolving Neutral Types */
|
||||
bidi_resolveNeutrals(&type_rl_list, base_dir);
|
||||
bidi_resolveNeutrals(charset_ops, achars, len, &type_rl_list, base_dir);
|
||||
|
||||
/* 5.Resolving implicit levels. */
|
||||
*pmax_level = bidi_resolveImplicit(&type_rl_list, base_level);
|
||||
@@ -826,4 +928,3 @@ Uint32 __mg_legacy_bidi_str_base_dir (const CHARSETOPS* charset_ops,
|
||||
|
||||
return base_dir;
|
||||
}
|
||||
|
||||
|
||||
+81
-9
@@ -1092,6 +1092,67 @@ nodraw_ret:
|
||||
}
|
||||
|
||||
#ifdef _MGFONT_FT2
|
||||
|
||||
static RGB blend_pixel(RGB font_pixel, RGB fg_color, RGB bg_color)
|
||||
{
|
||||
RGB result;
|
||||
|
||||
Uint8 src_pre_r, src_pre_g, src_pre_b;
|
||||
Uint8 bg_pre_r, bg_pre_g, bg_pre_b, alpha_bg;
|
||||
Uint8 out_r, out_g, out_b, alpha_out;
|
||||
|
||||
uint8_t alpha_font = 0.299 * font_pixel.r + 0.587 * font_pixel.g +
|
||||
0.114 * font_pixel.b;
|
||||
|
||||
uint16_t alpha_src = (fg_color.a * alpha_font + 127) / 255;
|
||||
|
||||
if (alpha_src == 0) {
|
||||
result = bg_color;
|
||||
goto out;
|
||||
}
|
||||
|
||||
src_pre_r = (fg_color.r * alpha_src + 127) / 255;
|
||||
src_pre_g = (fg_color.g * alpha_src + 127) / 255;
|
||||
src_pre_b = (fg_color.b * alpha_src + 127) / 255;
|
||||
|
||||
bg_pre_r = (bg_color.r * bg_color.a + 127) / 255;
|
||||
bg_pre_g = (bg_color.g * bg_color.a + 127) / 255;
|
||||
bg_pre_b = (bg_color.b * bg_color.a + 127) / 255;
|
||||
alpha_bg = bg_color.a;
|
||||
|
||||
out_r = src_pre_r + (bg_pre_r * (255 - alpha_src)) / 255;
|
||||
out_g = src_pre_g + (bg_pre_g * (255 - alpha_src)) / 255;
|
||||
out_b = src_pre_b + (bg_pre_b * (255 - alpha_src)) / 255;
|
||||
alpha_out = alpha_src + (alpha_bg * (255 - alpha_src)) / 255;
|
||||
|
||||
if (out_r > 255) {
|
||||
out_r = 255;
|
||||
}
|
||||
|
||||
if (out_g > 255) {
|
||||
out_g = 255;
|
||||
}
|
||||
|
||||
if (out_b > 255) {
|
||||
out_b = 255;
|
||||
}
|
||||
|
||||
if (alpha_out > 0) {
|
||||
result.r = (out_r * 255 + alpha_out / 2) / alpha_out;
|
||||
result.g = (out_g * 255 + alpha_out / 2) / alpha_out;
|
||||
result.b = (out_b * 255 + alpha_out / 2) / alpha_out;
|
||||
result.a = (uint8_t) alpha_out;
|
||||
} else {
|
||||
result.r = 0;
|
||||
result.g = 0;
|
||||
result.b = 0;
|
||||
result.a = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
|
||||
SCANLINE_CTXT* ctxt)
|
||||
{
|
||||
@@ -1112,8 +1173,8 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
|
||||
ctxt->glyph_ascent, ctxt->glyph_line,
|
||||
ctxt->glyph_advance);
|
||||
|
||||
GAL_GetRGB (pdc->textcolor, pdc->surface->format, &rgba_fg.r,
|
||||
&rgba_fg.g, &rgba_fg.b);
|
||||
GAL_GetRGBA (pdc->textcolor, pdc->surface->format, &rgba_fg.r,
|
||||
&rgba_fg.g, &rgba_fg.b, &rgba_fg.a);
|
||||
|
||||
for (x = 0; x < ctxt->bmp_w; x++) {
|
||||
if (!PtInRect (&pdc->rc_output, x+xpos, ypos)) {
|
||||
@@ -1130,8 +1191,8 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
|
||||
_glyph_move_to_pixel (pdc, x+xpos, ypos);
|
||||
pixel = _mem_get_pixel(pdc->cur_dst, GAL_BytesPerPixel (pdc->surface));
|
||||
|
||||
GAL_GetRGB (pixel, pdc->surface->format, &rgba_cur.r,
|
||||
&rgba_cur.g, &rgba_cur.b);
|
||||
GAL_GetRGBA (pixel, pdc->surface->format, &rgba_cur.r,
|
||||
&rgba_cur.g, &rgba_cur.b, &rgba_cur.a);
|
||||
|
||||
#define C_ALPHA(p, Cs, Cd) \
|
||||
if (*p++) { \
|
||||
@@ -1140,14 +1201,25 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
|
||||
Cd = sub_val >> 8; \
|
||||
}
|
||||
|
||||
C_ALPHA(bits, rgba_fg.r, rgba_cur.r);
|
||||
C_ALPHA(bits, rgba_fg.g, rgba_cur.g);
|
||||
C_ALPHA(bits, rgba_fg.b, rgba_cur.b);
|
||||
if (rgba_cur.r == 0 && rgba_cur.g == 0 && rgba_cur.b == 0 &&
|
||||
rgba_cur.a == 0) {
|
||||
RGB font_pixel = {bits[0], bits[1], bits[2], 255};
|
||||
RGB ret = blend_pixel(font_pixel, rgba_fg, rgba_cur);
|
||||
rgba_cur = ret;
|
||||
bits += 3;
|
||||
}
|
||||
else {
|
||||
C_ALPHA(bits, rgba_fg.r, rgba_cur.r);
|
||||
C_ALPHA(bits, rgba_fg.g, rgba_cur.g);
|
||||
C_ALPHA(bits, rgba_fg.b, rgba_cur.b);
|
||||
rgba_cur.a = 255.0;
|
||||
}
|
||||
|
||||
|
||||
#undef C_ALPHA
|
||||
|
||||
pdc->cur_pixel = GAL_MapRGB (pdc->surface->format, rgba_cur.r,
|
||||
rgba_cur.g, rgba_cur.b);
|
||||
pdc->cur_pixel = GAL_MapRGBA (pdc->surface->format, rgba_cur.r,
|
||||
rgba_cur.g, rgba_cur.b, rgba_cur.a);
|
||||
|
||||
if (pdc->cur_pixel != pixel) {
|
||||
_glyph_draw_pixel (pdc, x+xpos, ypos, pdc->cur_pixel);
|
||||
|
||||
Reference in New Issue
Block a user