mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2025-05-09 08:02:40 +08:00
Compare commits
12 Commits
ver-5-0-11
...
master
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0d1f1f028a | ||
![]() |
d4add19e6a | ||
![]() |
bfaeae0023 | ||
![]() |
70705c7db0 | ||
![]() |
517d74a2d2 | ||
![]() |
d68eee3c90 | ||
![]() |
e575e7c69d | ||
![]() |
d059fc8de2 | ||
![]() |
5d9d787dac | ||
![]() |
9696fbb3ba | ||
![]() |
800329086e | ||
![]() |
11be6af9d3 |
@ -1,5 +1,7 @@
|
||||
# Release Notes
|
||||
|
||||
- [Version 5.0.12](#version-5012)
|
||||
+ [What's new in version 5.0.12](#whats-new-in-version-5012)
|
||||
- [Version 5.0.11](#version-5011)
|
||||
+ [What's new in version 5.0.11](#whats-new-in-version-5011)
|
||||
- [Version 5.0.10](#version-5010)
|
||||
@ -28,6 +30,26 @@
|
||||
+ [Changes leading to incompatibility](#changes-leading-to-incompatibility)
|
||||
+ [Deprecated APIs](#deprecated-apis)
|
||||
|
||||
## Version 5.0.12
|
||||
|
||||
On May 10, 2023, FMSoft announces the availability of MiniGUI 5.0.12,
|
||||
which is an enhancement release with some minor enhancements
|
||||
of MiniGUI 5.0.x.
|
||||
|
||||
### What's new in version 5.0.12
|
||||
|
||||
In this version, we made some enhancements:
|
||||
|
||||
* ENHANCEMENTS:
|
||||
- Add new API `GetACharsExtentPointEx()`.
|
||||
- Add new APIs `GetTabbedACharsExtent()`, `GetTabbedACharsExtentPoint()`,
|
||||
and `GetTabbedACharsExtentPointEx()`.
|
||||
- Enhance two APIs `GetTextExtentPoint()` and `GetTabbedTextExtentPoint()`
|
||||
to support BIDI charsets.
|
||||
- Tune management of tick count.
|
||||
* BUGFIXING:
|
||||
- Fix a typo: `Achar2UChar()` to `AChar2UChar()`.
|
||||
|
||||
## Version 5.0.11
|
||||
|
||||
On Dec. 31, 2022, FMSoft announces the availability of MiniGUI 5.0.11,
|
||||
|
@ -1,4 +1,4 @@
|
||||
Version 5.0.11 (2022/12/31)
|
||||
Version 5.0.12 (2023/04/30)
|
||||
|
||||
This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.60)
|
||||
AC_INIT(libminigui, 5.0.11)
|
||||
AC_INIT(libminigui, 5.0.12)
|
||||
AC_CONFIG_SRCDIR(src/main/main.c)
|
||||
|
||||
dnl Set various version strings - taken gratefully from the SDL sources
|
||||
@ -16,9 +16,9 @@ dnl Set various version strings - taken gratefully from the SDL sources
|
||||
#
|
||||
MINIGUI_MAJOR_VERSION=5
|
||||
MINIGUI_MINOR_VERSION=0
|
||||
MINIGUI_MICRO_VERSION=11
|
||||
MINIGUI_INTERFACE_AGE=1
|
||||
MINIGUI_BINARY_AGE=1
|
||||
MINIGUI_MICRO_VERSION=12
|
||||
MINIGUI_INTERFACE_AGE=0
|
||||
MINIGUI_BINARY_AGE=2
|
||||
MINIGUI_VERSION=$MINIGUI_MAJOR_VERSION.$MINIGUI_MINOR_VERSION.$MINIGUI_MICRO_VERSION
|
||||
|
||||
AC_SUBST(MINIGUI_MAJOR_VERSION)
|
||||
|
101
include/gdi.h
101
include/gdi.h
@ -12632,7 +12632,7 @@ MG_EXPORT int GUIAPI BIDIGetTextVisualAChars (LOGFONT* log_font,
|
||||
* Achar32* achars, int nr_achars, int pel,
|
||||
* void* extra, CB_REVERSE_ARRAY cb_reverse_extra)
|
||||
* \brief Reorder the specified logical glyph string in visual order and
|
||||
* reorder an extra array to reflect the visule order of the achars.
|
||||
* reorder an extra array to reflect the visual order of the achars.
|
||||
*
|
||||
* This function reorders the logical glyph string in place to visual order.
|
||||
* If \a extra and \a cb_reverse_extra are both not NULL, it also reorders
|
||||
@ -12837,6 +12837,105 @@ MG_EXPORT int GUIAPI GetACharsExtent (HDC hdc, Achar32* achars, int nr_achars,
|
||||
MG_EXPORT int GUIAPI GetACharsExtentPoint (HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, \
|
||||
* int nr_achars, int max_extent, int* dx_chars, SIZE* size)
|
||||
* \brief Get the visual extent value of an achar string.
|
||||
*
|
||||
* This function gets the visual extent value of a glpyh string.
|
||||
* Note that this function ignore all breaks in the achar string.
|
||||
*
|
||||
* \param hdc The device context.
|
||||
* \param achars The pointer to the achar string.
|
||||
* \param nr_achars The length of the achar string len.
|
||||
* \param max_extent The maximal output extent value.
|
||||
* \param dx_achars The output positions of each character in the text will be
|
||||
* returned through this pointer. It can be NULL.
|
||||
* \param size The real extent of all visual achars in the achar string.
|
||||
*
|
||||
* \return The index of the last achar which can be fit to the extent.
|
||||
*
|
||||
* \sa GetACharsExtentPoint
|
||||
*
|
||||
* Since 5.0.12
|
||||
*/
|
||||
MG_EXPORT int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, int* dx_achars, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI GetTabbedACharsExtent (HDC hdc, Achar32* achars,
|
||||
* int nr_achars, SIZE* size)
|
||||
* \brief Get visual extent value of an achar string.
|
||||
*
|
||||
* This function gets the extent value of an achar string on a DC. Note that
|
||||
* this function will ignore all breaks in the achar string.
|
||||
*
|
||||
* \param hdc The device context.
|
||||
* \param achars The pointer to the achar string.
|
||||
* \param nr_achars The length of the achar string.
|
||||
* \param size The buffer restoring the extents of the achar strings.
|
||||
*
|
||||
* \return The extent of the achar string.
|
||||
*
|
||||
* \sa GetTabbedACharsExtentPoint
|
||||
*
|
||||
* Since 5.0.12
|
||||
*/
|
||||
MG_EXPORT int GUIAPI GetTabbedACharsExtent (HDC hdc, Achar32* achars,
|
||||
int nr_achars, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI GetTabbedACharsExtentPoint (HDC hdc, Achar32* achars,
|
||||
* int nr_achars, int max_extent, SIZE* size)
|
||||
* \brief Get the visual extent value of an achar string.
|
||||
*
|
||||
* This function gets the visual extent value of a glpyh string.
|
||||
* Note that this function ignore all breaks in the achar string.
|
||||
*
|
||||
* \param hdc The device context.
|
||||
* \param achars The pointer to the achar string.
|
||||
* \param nr_achars The length of the achar string len.
|
||||
* \param max_extent The maximal output extent value.
|
||||
* \param size The real extent of all visual achars in the achar string.
|
||||
*
|
||||
* \return The the index of the last achar which can be fit to the extent.
|
||||
*
|
||||
* \sa GetTabbedACharsExtentPointEx
|
||||
*
|
||||
* Since 5.0.12
|
||||
*/
|
||||
MG_EXPORT int GUIAPI GetTabbedACharsExtentPoint (HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI GetTabbedACharsExtentPointEx (HDC hdc,
|
||||
* Achar32* achars, int nr_achars, int max_extent,
|
||||
* int* dx_chars, int* dy_chars, SIZE* size)
|
||||
* \brief Get the visual extent value of an achar string.
|
||||
*
|
||||
* This function gets the visual extent value of a glpyh string.
|
||||
* Note that this function ignore all breaks in the achar string.
|
||||
*
|
||||
* \param hdc The device context.
|
||||
* \param achars The pointer to the achar string.
|
||||
* \param nr_achars The length of the achar string len.
|
||||
* \param max_extent The maximal output extent value.
|
||||
* \param dx_achars The output x-positions of each character in the text
|
||||
* will be returned through this pointer. It can be NULL.
|
||||
* \param dy_achars The output y-positions of each character in the text
|
||||
* will be returned through this pointer. It can be NULL.
|
||||
* \param size The real extent of all visual achars in the achar string.
|
||||
*
|
||||
* \return The index of the last achar which can be fit to the extent.
|
||||
*
|
||||
* \sa GetTabbedACharsExtentPoint
|
||||
*
|
||||
* Since 5.0.12
|
||||
*/
|
||||
MG_EXPORT int GUIAPI GetTabbedACharsExtentPointEx (HDC hdc,
|
||||
Achar32* achars, int nr_achars, int max_extent,
|
||||
int* dx_achars, int* dy_achars, SIZE* size);
|
||||
|
||||
/**
|
||||
* \fn Glyph32 GUIAPI GetGlyphValue (LOGFONT* logfont, const char* mchar, \
|
||||
* int mchar_len, const char* pre_mchar, int pre_len)
|
||||
|
@ -735,8 +735,7 @@ Achar32* __mg_legacy_bidi_map_reorder (const CHARSETOPS* charset_ops,
|
||||
run_pos = node_p->pos;
|
||||
run_len = node_p->len;
|
||||
|
||||
for (i=0; i<run_len; i++)
|
||||
{
|
||||
for (i=0; i<run_len; i++) {
|
||||
(map+run_pos+i)->is_rtol = (node_p)->level & 1;
|
||||
}
|
||||
}
|
||||
|
@ -141,6 +141,14 @@ BOOL mg_InitDesktop (void)
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static IDLEHANDLER std_idle_handler;
|
||||
|
||||
static BOOL idle_handler_for_desktop_thread (MSGQUEUE *msg_queue, BOOL wait)
|
||||
{
|
||||
__mg_update_tick_count (NULL);
|
||||
return std_idle_handler (msg_queue, wait);
|
||||
}
|
||||
|
||||
void* __kernel_desktop_main (void* data)
|
||||
{
|
||||
MSG Msg;
|
||||
@ -152,8 +160,10 @@ void* __kernel_desktop_main (void* data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* for threads mode, the idle handler for desktop thread is NULL */
|
||||
__mg_dsk_msg_queue->OnIdle = NULL;
|
||||
/* For bug reported in Issue #116, under threads mode, the idle handler
|
||||
for the desktop thread should call __mg_update_tick_count () */
|
||||
std_idle_handler = __mg_dsk_msg_queue->OnIdle;
|
||||
__mg_dsk_msg_queue->OnIdle = idle_handler_for_desktop_thread;
|
||||
|
||||
/* init desktop window */
|
||||
init_desktop_win ();
|
||||
|
@ -391,14 +391,6 @@ static BOOL InstallSEGVHandler (void)
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
static IDLEHANDLER std_idle_handler;
|
||||
|
||||
static BOOL idle_handler_for_main_thread (MSGQUEUE *msg_queue, BOOL wait)
|
||||
{
|
||||
__mg_update_tick_count (NULL);
|
||||
return std_idle_handler (msg_queue, wait);
|
||||
}
|
||||
|
||||
int GUIAPI InitGUI (int args, const char *agr[])
|
||||
{
|
||||
char engine [LEN_ENGINE_NAME + 1];
|
||||
@ -583,11 +575,6 @@ int GUIAPI InitGUI (int args, const char *agr[])
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* for threads mode, the idle handler for the main threads should
|
||||
call __mg_update_tick_count () */
|
||||
std_idle_handler = msg_queue->OnIdle;
|
||||
msg_queue->OnIdle = idle_handler_for_main_thread;
|
||||
|
||||
/* init timer for tick counter */
|
||||
step++;
|
||||
if (!mg_InitTimer (FALSE)) {
|
||||
|
@ -293,6 +293,11 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
||||
TIMER** timer_slots;
|
||||
PMSGQUEUE pMsgQueue;
|
||||
|
||||
#ifndef _MGRM_THREADS
|
||||
/* Force to update tick count */
|
||||
GetTickCount();
|
||||
#endif
|
||||
|
||||
if (id == 0) {
|
||||
_WRN_PRINTF ("bad identifier (%ld).\n", id);
|
||||
return FALSE;
|
||||
@ -415,7 +420,12 @@ int GUIAPI KillTimer (HWND hWnd, LINT id)
|
||||
int i;
|
||||
int killed = 0;
|
||||
MSGQUEUE* msg_queue;
|
||||
|
||||
|
||||
#ifndef _MGRM_THREADS
|
||||
/* Force to update tick count */
|
||||
GetTickCount();
|
||||
#endif
|
||||
|
||||
msg_queue = getMsgQueueForThisThread ();
|
||||
if (msg_queue) {
|
||||
|
||||
@ -447,7 +457,12 @@ BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
||||
{
|
||||
int i;
|
||||
MSGQUEUE* msg_queue;
|
||||
|
||||
|
||||
#ifndef _MGRM_THREADS
|
||||
/* Force to update tick count */
|
||||
GetTickCount();
|
||||
#endif
|
||||
|
||||
if (id == 0)
|
||||
return FALSE;
|
||||
|
||||
@ -482,6 +497,11 @@ BOOL GUIAPI IsTimerInstalled (HWND hWnd, LINT id)
|
||||
int i;
|
||||
TIMER** timer_slots;
|
||||
|
||||
#ifndef _MGRM_THREADS
|
||||
/* Force to update tick count */
|
||||
GetTickCount();
|
||||
#endif
|
||||
|
||||
if (id == 0)
|
||||
return FALSE;
|
||||
|
||||
@ -507,6 +527,11 @@ BOOL GUIAPI HaveFreeTimer (void)
|
||||
int i;
|
||||
TIMER** timer_slots;
|
||||
|
||||
#ifndef _MGRM_THREADS
|
||||
/* Force to update tick count */
|
||||
GetTickCount();
|
||||
#endif
|
||||
|
||||
timer_slots = getTimerSlotsForThisThread (NULL);
|
||||
if (timer_slots) {
|
||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
||||
@ -531,179 +556,12 @@ DWORD GUIAPI GetTickCount (void)
|
||||
else {
|
||||
__mg_tick_counter = SHAREDRES_TIMER_COUNTER;
|
||||
}
|
||||
#else /* defined _MGRM_PROCESSES */
|
||||
#elif defined(_MGRM_STANDALONE)
|
||||
__mg_tick_counter = __mg_os_get_time_ticks ();
|
||||
#endif /* not defined _MGRM_PROCESSES */
|
||||
#else /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */
|
||||
/* do nothing here because the desktop thread updates the tick count */
|
||||
#endif /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */
|
||||
|
||||
return __mg_tick_counter;
|
||||
}
|
||||
|
||||
#if 0 /* deprecated code */
|
||||
|
||||
/* Since 5.0.0, we no longer use the timer thread for MiniGUI-Threads runmode */
|
||||
in message queue */
|
||||
|
||||
/* timer entry for thread version */
|
||||
#ifdef _MGRM_THREADS
|
||||
|
||||
#ifdef __AOS__
|
||||
|
||||
#include "os_api.h"
|
||||
|
||||
static OS_TIMER_ID __mg_os_timer = 0;
|
||||
|
||||
#else /* __AOS__ */
|
||||
static void* TimerEntry (void* data)
|
||||
{
|
||||
sem_post ((sem_t*)data);
|
||||
|
||||
while (__mg_quiting_stage > _MG_QUITING_STAGE_TIMER) {
|
||||
__mg_os_time_delay (10);
|
||||
__mg_update_tick_count (NULL);
|
||||
}
|
||||
|
||||
/* printf("quit from TimerEntry()\n"); */
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !__AOS__ */
|
||||
|
||||
int __mg_timer_init (void)
|
||||
{
|
||||
if (!mg_InitTimer ()) {
|
||||
fprintf (stderr, "KERNEL>timer: Init Timer failure.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __AOS__
|
||||
__mg_os_timer = tp_os_timer_create ("mgtimer", __mg_update_tick_count,
|
||||
NULL, AOS_TIMER_TICKT,
|
||||
OS_AUTO_ACTIVATE | OS_AUTO_LOAD);
|
||||
#else /* __AOS__ */
|
||||
{
|
||||
sem_t wait;
|
||||
sem_init (&wait, 0, 0);
|
||||
pthread_create (&__mg_timer, NULL, TimerEntry, &wait);
|
||||
sem_wait (&wait);
|
||||
sem_destroy (&wait);
|
||||
}
|
||||
#endif /* !__AOS__ */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mg_TerminateTimer (void)
|
||||
{
|
||||
#ifdef __AOS__
|
||||
tp_os_timer_delete (__mg_os_timer);
|
||||
#endif
|
||||
|
||||
#ifdef __WINBOND_SWLINUX__
|
||||
pthread_detach (__mg_timer); /* XXX: Can we pthread_join()? */
|
||||
#else
|
||||
pthread_join (__mg_timer, NULL);
|
||||
#endif /* __WINBOND_SWLINUX__ */
|
||||
|
||||
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
||||
pthread_mutex_destroy (&timerLock);
|
||||
#endif
|
||||
|
||||
#if 0 /* deprecated code */
|
||||
/* Since 5.0.0, we allocate timer slots per thread, and manage the time slots
|
||||
in message queue */
|
||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
||||
if (timerstr[i] != NULL)
|
||||
free ( timerstr[i] );
|
||||
timerstr[i] = NULL;
|
||||
}
|
||||
|
||||
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
||||
pthread_mutex_destroy (&timerLock);
|
||||
#endif
|
||||
#endif /* deprecated code */
|
||||
}
|
||||
|
||||
#else /* defined _MGRM_THREADS */
|
||||
#endif /* defined _MGRM_THREADS */
|
||||
|
||||
/* Since 5.0.0, we use timer slots per thread, and manage the time slots
|
||||
in message queue */
|
||||
static TIMER *timerstr[DEF_NR_TIMERS];
|
||||
|
||||
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
||||
/* lock for protecting timerstr */
|
||||
static pthread_mutex_t timerLock;
|
||||
#define TIMER_LOCK() pthread_mutex_lock(&timerLock)
|
||||
#define TIMER_UNLOCK() pthread_mutex_unlock(&timerLock)
|
||||
#else
|
||||
#define TIMER_LOCK()
|
||||
#define TIMER_UNLOCK()
|
||||
#endif
|
||||
|
||||
int __mg_get_timer_slot (HWND hWnd, int id)
|
||||
{
|
||||
int i;
|
||||
int slot = -1;
|
||||
|
||||
TIMER_LOCK ();
|
||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
||||
if (timerstr[i] != NULL) {
|
||||
if (timerstr[i]->hWnd == hWnd && timerstr[i]->id == id) {
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_UNLOCK ();
|
||||
return slot;
|
||||
}
|
||||
|
||||
void __mg_move_timer_last (TIMER* timer, int slot)
|
||||
{
|
||||
if (slot < 0 || slot >= DEF_NR_TIMERS)
|
||||
return;
|
||||
|
||||
TIMER_LOCK ();
|
||||
|
||||
if (timer && timer->msg_queue) {
|
||||
/* The following code is already called in message.c...
|
||||
* timer->ticks_current = 0;
|
||||
* timer->msg_queue->expired_timer_mask &= ~(0x01UL << slot);
|
||||
*/
|
||||
|
||||
if (slot != (DEF_NR_TIMERS - 1)) {
|
||||
TIMER* t;
|
||||
|
||||
if (timer->msg_queue->expired_timer_mask & (0x01UL << (DEF_NR_TIMERS -1))) {
|
||||
timer->msg_queue->expired_timer_mask |= (0x01UL << slot);
|
||||
timer->msg_queue->expired_timer_mask &= ~(0x01UL << (DEF_NR_TIMERS -1));
|
||||
}
|
||||
|
||||
t = timerstr [DEF_NR_TIMERS - 1];
|
||||
timerstr [DEF_NR_TIMERS - 1] = timerstr [slot];
|
||||
timerstr [slot] = t;
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_UNLOCK ();
|
||||
return;
|
||||
}
|
||||
|
||||
TIMER* __mg_get_timer (int slot)
|
||||
{
|
||||
TIMER** timer_slots;
|
||||
|
||||
if (slot < 0 || slot >= DEF_NR_TIMERS)
|
||||
return NULL;
|
||||
|
||||
timer_slots = getTimerSlotsForThisThread (NULL);
|
||||
if (timer_slots) {
|
||||
return timer_slots[slot];
|
||||
}
|
||||
|
||||
_WRN_PRINTF ("called for non message thread\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* deprecated code */
|
||||
|
||||
|
@ -307,7 +307,7 @@ static int RealEngine_GetInfo (RealFBInfo * realfb_info)
|
||||
|
||||
real_device->screen = GAL_CreateRGBSurface (GAL_SWSURFACE,
|
||||
0, 0, real_vformat.BitsPerPixel, real_vformat.Rmask,
|
||||
real_vformat.Gmask, real_vformat.Bmask, 0);
|
||||
real_vformat.Gmask, real_vformat.Bmask, real_vformat.Amask);
|
||||
|
||||
if (real_device->screen == NULL)
|
||||
_ERR_PRINTF ("NEWGAL>SHADOW: can't create screen of real engine.\n");
|
||||
|
@ -200,7 +200,7 @@ Uint16 GUIAPI GetACharBidiType (LOGFONT* log_font, Achar32 chv)
|
||||
|
||||
#include "unicode-ops.h"
|
||||
|
||||
Uchar32 GUIAPI Achar2UChar(LOGFONT* logfont, Achar32 chv)
|
||||
Uchar32 GUIAPI AChar2UChar(LOGFONT* logfont, Achar32 chv)
|
||||
{
|
||||
Uchar32 uc;
|
||||
DEVFONT* devfont = SELECT_DEVFONT_BY_ACHAR(logfont, chv);
|
||||
|
@ -612,8 +612,7 @@ int _gdi_reorder_text (PDC pdc, const unsigned char* text, int text_len,
|
||||
(NULL, 0, text + i, 1)))
|
||||
return (text_len-i-1);
|
||||
|
||||
char_type = sbc_devfont->charset_ops->char_type
|
||||
(chv);
|
||||
char_type = sbc_devfont->charset_ops->char_type (chv);
|
||||
|
||||
gv = GetGlyphValueAlt (pdc->pLogFont, chv);
|
||||
if (gv == INV_GLYPH_VALUE)
|
||||
|
@ -533,6 +533,113 @@ int GUIAPI TabbedTextOutEx (HDC hdc, int x, int y, const char* spText,
|
||||
return advance;
|
||||
}
|
||||
|
||||
#define SZ_BUFF_IN_STACK 256
|
||||
|
||||
static int get_tabbed_text_extent_point_for_bidi(HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC(hdc);
|
||||
LOGFONT *log_font = pdc->pLogFont;
|
||||
DEVFONT* sbc_devfont = log_font->devfonts[0];
|
||||
Achar32 achars_buff[SZ_BUFF_IN_STACK];
|
||||
ACHARMAPINFO achars_map_buff[SZ_BUFF_IN_STACK];
|
||||
Achar32 *achars;
|
||||
ACHARMAPINFO* achars_map;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen(text);
|
||||
if (len <= SZ_BUFF_IN_STACK) {
|
||||
achars = achars_buff;
|
||||
achars_map = achars_map_buff;
|
||||
}
|
||||
else {
|
||||
achars = NULL;
|
||||
achars_map = NULL;
|
||||
}
|
||||
|
||||
int nr_fit_achars = 0;
|
||||
|
||||
int nr_achars = BIDIGetTextVisualAChars(log_font, text, len,
|
||||
&achars, &achars_map);
|
||||
if (nr_achars <= 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
_gdi_start_new_line(pdc);
|
||||
|
||||
int tab_width = sbc_devfont->font_ops->get_ave_width(log_font, sbc_devfont)
|
||||
* pdc->tabstop;
|
||||
int line_height = log_font->size + pdc->alExtra + pdc->blExtra;
|
||||
|
||||
size->cx = 0;
|
||||
size->cy = line_height;
|
||||
|
||||
int left_achars = nr_achars;
|
||||
int last_line_width = 0;
|
||||
while (left_achars > 0) {
|
||||
if (pos_chars)
|
||||
pos_chars[nr_fit_achars] = achars_map[nr_fit_achars].byte_index;
|
||||
if (dx_chars)
|
||||
dx_chars[nr_fit_achars] = last_line_width;
|
||||
size->cx = last_line_width;
|
||||
|
||||
Uint32 achar_type = GetACharType(log_font, achars[nr_fit_achars]);
|
||||
Glyph32 gv = GetGlyphValueAlt(log_font, achars[nr_fit_achars]);
|
||||
|
||||
int adv_x = 0, adv_y = 0;
|
||||
switch (achar_type & ACHARTYPE_BASIC_MASK) {
|
||||
case ACHAR_BASIC_ZEROWIDTH:
|
||||
adv_x = adv_y = 0;
|
||||
break;
|
||||
case ACHAR_BASIC_LF:
|
||||
adv_y = line_height;
|
||||
case ACHAR_BASIC_CR:
|
||||
adv_x = 0;
|
||||
if (last_line_width > size->cx) {
|
||||
size->cx = last_line_width;
|
||||
}
|
||||
last_line_width = 0;
|
||||
_gdi_start_new_line(pdc);
|
||||
break;
|
||||
|
||||
case ACHAR_BASIC_HT:
|
||||
adv_x = tab_width;
|
||||
last_line_width += tab_width;
|
||||
_gdi_start_new_line(pdc);
|
||||
break;
|
||||
|
||||
default:
|
||||
last_line_width += _gdi_get_glyph_advance (pdc, gv,
|
||||
(pdc->ta_flags & TA_X_MASK) != TA_RIGHT,
|
||||
0, 0, &adv_x, &adv_y, NULL);
|
||||
last_line_width += pdc->cExtra;
|
||||
break;
|
||||
}
|
||||
|
||||
if (max_extent > 0 && last_line_width > max_extent) {
|
||||
break;
|
||||
}
|
||||
|
||||
size->cx += adv_x;
|
||||
size->cy += adv_y;
|
||||
if (last_line_width > size->cx)
|
||||
size->cx = last_line_width;
|
||||
left_achars--;
|
||||
nr_fit_achars++;
|
||||
}
|
||||
|
||||
if (fit_chars)
|
||||
*fit_chars = nr_fit_achars;
|
||||
|
||||
done:
|
||||
if (achars != NULL && achars != achars_buff)
|
||||
free(achars);
|
||||
if (achars_map != NULL && achars_map != achars_map_buff)
|
||||
free(achars_map);
|
||||
return nr_fit_achars;
|
||||
}
|
||||
|
||||
int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
@ -553,9 +660,11 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
/* set size to zero first */
|
||||
size->cx = size->cy = 0;
|
||||
|
||||
/* This function does not support BIDI */
|
||||
if (mbc_devfont && pdc->bidi_flags && mbc_devfont->charset_ops->bidi_char_type)
|
||||
return -1;
|
||||
if (mbc_devfont && pdc->bidi_flags &&
|
||||
mbc_devfont->charset_ops->bidi_char_type) {
|
||||
return get_tabbed_text_extent_point_for_bidi(hdc, text, len,
|
||||
max_extent, fit_chars, pos_chars, dx_chars, size);
|
||||
}
|
||||
|
||||
_gdi_start_new_line (pdc);
|
||||
|
||||
@ -569,6 +678,7 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
pos_chars [char_count] = len - left_bytes;
|
||||
if (dx_chars)
|
||||
dx_chars [char_count] = last_line_width;
|
||||
size->cx = last_line_width;
|
||||
|
||||
devfont = NULL;
|
||||
len_cur_char = 0;
|
||||
@ -599,7 +709,6 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text,
|
||||
|
||||
switch (char_type & ACHARTYPE_BASIC_MASK) {
|
||||
case ACHAR_BASIC_ZEROWIDTH:
|
||||
case ACHAR_BASIC_VOWEL:
|
||||
break;
|
||||
case ACHAR_BASIC_LF:
|
||||
size->cy += line_height;
|
||||
@ -642,3 +751,94 @@ ret:
|
||||
return len - left_bytes;
|
||||
}
|
||||
|
||||
int GUIAPI GetTabbedACharsExtentPointEx(HDC hdc,
|
||||
Achar32* achars, int nr_achars, int max_extent,
|
||||
int* dx_achars, int* dy_achars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC(hdc);
|
||||
LOGFONT *log_font = pdc->pLogFont;
|
||||
DEVFONT* sbc_devfont = log_font->devfonts[0];
|
||||
int nr_fit_achars = 0;
|
||||
|
||||
_gdi_start_new_line(pdc);
|
||||
|
||||
int tab_width = sbc_devfont->font_ops->get_ave_width(log_font, sbc_devfont)
|
||||
* pdc->tabstop;
|
||||
int line_height = log_font->size + pdc->alExtra + pdc->blExtra;
|
||||
|
||||
size->cx = 0;
|
||||
size->cy = 0;
|
||||
|
||||
int left_achars = nr_achars;
|
||||
int last_line_width = 0;
|
||||
while (left_achars > 0) {
|
||||
if (dx_achars)
|
||||
dx_achars[nr_fit_achars] = last_line_width;
|
||||
if (dy_achars)
|
||||
dy_achars[nr_fit_achars] = size->cy;
|
||||
size->cx = last_line_width;
|
||||
|
||||
Uint32 achar_type = GetACharType(log_font, achars[nr_fit_achars]);
|
||||
Glyph32 gv = GetGlyphValueAlt(log_font, achars[nr_fit_achars]);
|
||||
|
||||
int adv_x = 0, adv_y = 0;
|
||||
switch (achar_type & ACHARTYPE_BASIC_MASK) {
|
||||
case ACHAR_BASIC_ZEROWIDTH:
|
||||
adv_x = adv_y = 0;
|
||||
break;
|
||||
case ACHAR_BASIC_LF:
|
||||
adv_y = line_height;
|
||||
case ACHAR_BASIC_CR:
|
||||
adv_x = 0;
|
||||
if (last_line_width > size->cx) {
|
||||
size->cx = last_line_width;
|
||||
}
|
||||
last_line_width = 0;
|
||||
_gdi_start_new_line(pdc);
|
||||
break;
|
||||
|
||||
case ACHAR_BASIC_HT:
|
||||
adv_x = tab_width;
|
||||
last_line_width += tab_width;
|
||||
_gdi_start_new_line(pdc);
|
||||
break;
|
||||
|
||||
default:
|
||||
last_line_width += _gdi_get_glyph_advance (pdc, gv,
|
||||
(pdc->ta_flags & TA_X_MASK) != TA_RIGHT,
|
||||
0, 0, &adv_x, &adv_y, NULL);
|
||||
last_line_width += pdc->cExtra;
|
||||
break;
|
||||
}
|
||||
|
||||
if (max_extent > 0 && last_line_width > max_extent) {
|
||||
break;
|
||||
}
|
||||
|
||||
size->cx += adv_x;
|
||||
size->cy += adv_y;
|
||||
if (last_line_width > size->cx)
|
||||
size->cx = last_line_width;
|
||||
left_achars--;
|
||||
nr_fit_achars++;
|
||||
}
|
||||
|
||||
size->cy += line_height;
|
||||
return nr_fit_achars;
|
||||
}
|
||||
|
||||
int GUIAPI GetTabbedACharsExtentPoint(HDC hdc, Achar32* achars,
|
||||
int nr_achars, int max_extent, SIZE* size)
|
||||
{
|
||||
return GetTabbedACharsExtentPointEx(hdc,
|
||||
achars, nr_achars, max_extent, NULL, NULL, size);
|
||||
}
|
||||
|
||||
int GUIAPI GetTabbedACharsExtent(HDC hdc, Achar32* achars,
|
||||
int nr_achars, SIZE* size)
|
||||
{
|
||||
GetTabbedACharsExtentPointEx(hdc,
|
||||
achars, nr_achars, -1, NULL, NULL, size);
|
||||
return size->cx;
|
||||
}
|
||||
|
||||
|
@ -319,7 +319,8 @@ typedef struct _TEXTOUTOMITTED_CTXT
|
||||
Uint32 max_extent;
|
||||
} TEXTOUTOMITTED_CTXT;
|
||||
|
||||
static BOOL cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int char_type)
|
||||
static BOOL
|
||||
cb_textout_omitted (void* context, Glyph32 glyph_value, unsigned int char_type)
|
||||
{
|
||||
TEXTOUTOMITTED_CTXT* ctxt = (TEXTOUTOMITTED_CTXT*)context;
|
||||
int adv_x, adv_y;
|
||||
@ -441,9 +442,82 @@ int GUIAPI TextOutOmitted (HDC hdc, int x, int y,
|
||||
|
||||
#undef STRDOT_LEN
|
||||
|
||||
int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len,
|
||||
int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
#define SZ_BUFF_IN_STACK 256
|
||||
|
||||
static int get_text_extent_point_for_bidi(HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC(hdc);
|
||||
LOGFONT *log_font = pdc->pLogFont;
|
||||
Achar32 achars_buff[SZ_BUFF_IN_STACK];
|
||||
ACHARMAPINFO achars_map_buff[SZ_BUFF_IN_STACK];
|
||||
int dx_achars_buff[SZ_BUFF_IN_STACK];
|
||||
Achar32 *achars;
|
||||
ACHARMAPINFO* achars_map;
|
||||
int *dx_achars = NULL;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen(text);
|
||||
if (len <= SZ_BUFF_IN_STACK) {
|
||||
achars = achars_buff;
|
||||
achars_map = achars_map_buff;
|
||||
}
|
||||
else {
|
||||
achars = NULL;
|
||||
achars_map = NULL;
|
||||
}
|
||||
|
||||
int nr_fit_achars = 0;
|
||||
|
||||
int nr_achars = BIDIGetTextVisualAChars(log_font, text, len,
|
||||
&achars, &achars_map);
|
||||
if (nr_achars <= 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (nr_achars <= SZ_BUFF_IN_STACK) {
|
||||
dx_achars = dx_achars_buff;
|
||||
}
|
||||
else {
|
||||
dx_achars = malloc(sizeof(int) * nr_achars);
|
||||
}
|
||||
|
||||
if (dx_chars == NULL || achars == NULL || achars_map == NULL)
|
||||
goto done;
|
||||
|
||||
nr_fit_achars = GetACharsExtentPointEx(hdc, achars, nr_achars,
|
||||
max_extent, dx_achars, size);
|
||||
|
||||
if (fit_chars) {
|
||||
*fit_chars = nr_fit_achars;
|
||||
}
|
||||
|
||||
if (pos_chars || dx_chars) {
|
||||
for (int i = 0; i < nr_fit_achars; i++) {
|
||||
if (pos_chars) {
|
||||
pos_chars[i] = achars_map[i].byte_index;
|
||||
}
|
||||
|
||||
if (dx_chars) {
|
||||
dx_chars[i] = dx_achars[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (achars != NULL && achars != achars_buff)
|
||||
free(achars);
|
||||
if (achars_map != NULL && achars_map != achars_map_buff)
|
||||
free(achars_map);
|
||||
if (dx_achars != NULL && dx_achars != dx_achars_buff)
|
||||
free(dx_achars);
|
||||
return nr_fit_achars;
|
||||
}
|
||||
|
||||
int GUIAPI GetTextExtentPoint (HDC hdc,
|
||||
const char* text, int len, int max_extent,
|
||||
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size)
|
||||
{
|
||||
PDC pdc = dc_HDC2PDC (hdc);
|
||||
LOGFONT* log_font = pdc->pLogFont;
|
||||
@ -459,8 +533,12 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len,
|
||||
size->cx = size->cy = 0;
|
||||
|
||||
/* This function does not support BIDI */
|
||||
if (mbc_devfont && pdc->bidi_flags && mbc_devfont->charset_ops->bidi_char_type)
|
||||
if (mbc_devfont && pdc->bidi_flags &&
|
||||
mbc_devfont->charset_ops->bidi_char_type) {
|
||||
get_text_extent_point_for_bidi(pdc, text, len, max_extent,
|
||||
fit_chars, pos_chars, dx_chars, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_gdi_start_new_line(pdc);
|
||||
|
||||
@ -538,8 +616,8 @@ int GUIAPI DrawACharString (HDC hdc, int startx, int starty,
|
||||
return ctxt.advance;
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, SIZE* size)
|
||||
int GUIAPI GetACharsExtentPointEx (HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, int *dx_achars, SIZE* size)
|
||||
{
|
||||
int i = 0;
|
||||
int advance = 0;
|
||||
@ -552,11 +630,15 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
size->cx = 0;
|
||||
size->cy = 0;
|
||||
|
||||
while(i < nr_achars){
|
||||
while (i < nr_achars){
|
||||
if (dx_achars) {
|
||||
dx_achars[i] = advance;
|
||||
}
|
||||
|
||||
devfont = SELECT_DEVFONT_BY_ACHAR(log_font, achars[i]);
|
||||
char_type = devfont->charset_ops->char_type(achars[i]);
|
||||
|
||||
if (check_zero_width (char_type)) {
|
||||
if (check_zero_width(char_type)) {
|
||||
adv_x = adv_y = 0;
|
||||
}
|
||||
else {
|
||||
@ -578,7 +660,7 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
|
||||
size->cx += adv_x;
|
||||
size->cy += adv_y;
|
||||
i ++;
|
||||
i++;
|
||||
}
|
||||
|
||||
_gdi_calc_glyphs_size_from_two_points (pdc, 0, 0,
|
||||
@ -587,6 +669,13 @@ int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
return i;
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtentPoint(HDC hdc, Achar32* achars, int nr_achars,
|
||||
int max_extent, SIZE* size)
|
||||
{
|
||||
return GetACharsExtentPointEx(hdc, achars, nr_achars, max_extent,
|
||||
NULL, size);
|
||||
}
|
||||
|
||||
int GUIAPI GetACharsExtent(HDC hdc, Achar32* achars, int nr_achars, SIZE* size)
|
||||
{
|
||||
int i = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user