mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-24 00:54:18 +08:00
add UCharCanonicalOrdering and others for composition and decomposition
This commit is contained in:
+14
-3
@@ -10,6 +10,8 @@ Please report any bugs and incompatibilities in
|
||||
|
||||
### What's new in this version
|
||||
|
||||
In this version, we mainly enhanced and tuned the APIs of font rendering.
|
||||
|
||||
#### Tunning the logical font APIs
|
||||
|
||||
The styles of LOGFONT changed.
|
||||
@@ -67,7 +69,7 @@ Note that `<underline>` and `<struckout>` are merged to `<decoration>`
|
||||
in order to keep the style string is still 6-character long.
|
||||
|
||||
Consequently, if you want to use the rendering method SUPIXEL for a TTF font,
|
||||
please define the font name in the following way:
|
||||
please define the logical font name in the following way:
|
||||
|
||||
ttf-Courier-rrncns-*-16-UTF-8
|
||||
|
||||
@@ -77,8 +79,8 @@ Moreover, the family name of a DEVFONT supports aliases since 3.4.0:
|
||||
|
||||
for example:
|
||||
|
||||
ttf-Arial,Sans serif-rrncnn-8-16-ISO8859-1,UTF-8
|
||||
ttf-Courier,Monospace-rrncnn-8-16-ISO8859-1,UTF-8
|
||||
ttf-Arial,Sans Serif-rrncnn-8-16-ISO8859-1,UTF-8
|
||||
ttf-Courier,Monospace,Serif-rrncnn-8-16-ISO8859-1,UTF-8
|
||||
|
||||
Note that the length of one DEVFONT name can not exceed 255 bytes.
|
||||
|
||||
@@ -90,11 +92,20 @@ if you want to get the height and descent data of one font.
|
||||
|
||||
* More fields added for GLYPHBITMAP struct in order to return the completed
|
||||
rasterized glyph bitmap information.
|
||||
|
||||
* `GetGlyphInfo` now can return the basic glyph type and break type of a
|
||||
UNICODE character. If the glyph is an ASCII character, the old `MCHAR_TYPE`
|
||||
can also be returned.
|
||||
|
||||
* Rename `mg_FT_LcdFilter` to `FT2LCDFilter` in order to follow MiniGUI naming
|
||||
rules.
|
||||
|
||||
#### New APIs
|
||||
|
||||
* `GetGlyphsByRules` function calculates and allocates the glyph string from
|
||||
a multi-byte string under the specified white space rule and transformation
|
||||
rule.
|
||||
|
||||
* `GetGlyphsExtentPointEx` function gets the visual extent information
|
||||
of a glyph string which can fit in a line with the specified maximal extent.
|
||||
|
||||
|
||||
+81
-7
@@ -6966,6 +6966,33 @@ MG_EXPORT UChar32 GUIAPI UCharToLower (UChar32 uc);
|
||||
/** Converts a glyph to the titlecase. */
|
||||
MG_EXPORT UChar32 GUIAPI UCharToTitle (UChar32 uc);
|
||||
|
||||
/** Determines the canonical combining class of a Unicode character.*/
|
||||
MG_EXPORT int GUIAPI UCharCombiningClass (UChar32 uc);
|
||||
|
||||
/**
|
||||
* Computes the canonical ordering of a string in-place.
|
||||
* This rearranges decomposed characters in the string
|
||||
* according to their combining classes.
|
||||
* See the Unicode manual for more information.
|
||||
*/
|
||||
MG_EXPORT void GUIAPI UCharCanonicalOrdering (UChar32 *string, int len);
|
||||
|
||||
/** Performs a single decomposition step of the Unicode canonical decomposition algorithm. */
|
||||
MG_EXPORT BOOL GUIAPI UCharCompose (UChar32 a, UChar32 b, UChar32 *ch);
|
||||
|
||||
/** Performs a single composition step of the Unicode canonical composition algorithm. */
|
||||
MG_EXPORT BOOL GUIAPI UCharDecompose (UChar32 ch, UChar32 *a, UChar32 *b);
|
||||
|
||||
/**
|
||||
* Computes the canonical or compatibility decomposition of a
|
||||
* Unicode character.
|
||||
*
|
||||
* For compatibility decomposition, pass TRUE for \a compat;
|
||||
* for canonical decomposition pass FALSE for \a compat.
|
||||
*/
|
||||
MG_EXPORT int GUIAPI UCharFullyDecompose (UChar32 ch, BOOL compat,
|
||||
UChar32 *result, int result_len);
|
||||
|
||||
#endif /* _MGCHARSET_UNICODE */
|
||||
|
||||
/**
|
||||
@@ -9016,6 +9043,21 @@ typedef enum {
|
||||
MG_EXPORT Glyph32 GUIAPI GetGlyphShape (LOGFONT* logfont, const char* mchar,
|
||||
int mchar_len, GLYPHSHAPETYPE shape_type);
|
||||
|
||||
/**
|
||||
* \fn BOOL GUIAPI GetMirrorGlyph (LOGFONT* logfont, Glyph32 glyph,
|
||||
* Glyph32* mirrored)
|
||||
* \brief Get the mirror glyph if possible.
|
||||
*
|
||||
* \param logfont The logical font.
|
||||
* \param glyph The glyph value.
|
||||
* \param mirrored The buffer to store the mirrored glyph if \a glyph
|
||||
* has a mirrored glyph.
|
||||
*
|
||||
* \return TRUE if success, FALSE on failure.
|
||||
*/
|
||||
MG_EXPORT BOOL GUIAPI GetMirrorGlyph (LOGFONT* logfont, Glyph32 glyph,
|
||||
Glyph32* mirrored);
|
||||
|
||||
/**
|
||||
* \fn int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value, \
|
||||
* int* adv_x, int* adv_y)
|
||||
@@ -9060,6 +9102,21 @@ MG_EXPORT int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value,
|
||||
MG_EXPORT int GUIAPI DrawGlyphString (HDC hdc, int x, int y, Glyph32* glyphs,
|
||||
int nr_glyphs, int* adv_x, int* adv_y);
|
||||
|
||||
/**
|
||||
* \fn Uint32 GUIAPI GetGlyphType (LOGFONT* logfont, Glyph32 glyph_value)
|
||||
* \brief Retriev the basic type of a glyph.
|
||||
*
|
||||
* This function retrieves the basic type of a glyph.
|
||||
*
|
||||
* \param logfont The logical font.
|
||||
* \param glyph_value The glyph value.
|
||||
*
|
||||
* \return The basic type of the specified glyph.
|
||||
*
|
||||
* \sa GetGlyphInfo, GetGlyphBIDIType
|
||||
*/
|
||||
MG_EXPORT Uint32 GUIAPI GetGlyphType (LOGFONT* logfont, Glyph32 glyph_value);
|
||||
|
||||
#define GLYPH_INFO_TYPE 0x01
|
||||
#define GLYPH_INFO_BIDI_TYPE 0x02
|
||||
#define GLYPH_INFO_METRICS 0x04
|
||||
@@ -9096,13 +9153,13 @@ typedef struct _GLYPHINFO {
|
||||
* - GLYPH_INFO_METRICS
|
||||
* - GLYPH_INFO_BMP
|
||||
*/
|
||||
unsigned int mask;
|
||||
Uint32 mask;
|
||||
|
||||
/** The glyph type */
|
||||
unsigned int glyph_type;
|
||||
Uint32 glyph_type;
|
||||
|
||||
/** The BIDI glyph type */
|
||||
unsigned int bidi_glyph_type;
|
||||
Uint32 bidi_glyph_type;
|
||||
|
||||
#if 0 // VincentWei: removed since 3.4.0
|
||||
/** The height of the glyph */
|
||||
@@ -9138,7 +9195,7 @@ typedef struct _GLYPHINFO {
|
||||
BITMAP prbitmap;
|
||||
} GLYPHINFO;
|
||||
|
||||
/**
|
||||
/**
|
||||
* \fn int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value, \
|
||||
* GLYPHINFO* glyph_info)
|
||||
* \brief Retriev the information of a glyph.
|
||||
@@ -9151,7 +9208,7 @@ typedef struct _GLYPHINFO {
|
||||
*
|
||||
* \note You must set glyph_info->mask to indicate what you want.
|
||||
*
|
||||
* \return The advance of the glyph string on baseline.
|
||||
* \return 0 if success, otherwise on failure.
|
||||
*
|
||||
* \sa GLYPHINFO
|
||||
*/
|
||||
@@ -9634,9 +9691,26 @@ MG_EXPORT int GUIAPI DrawGlyphStringEx (HDC hdc, const Glyph32* glyphs, int nr_g
|
||||
#define BIDI_NUMBER_TO_RTL(p) \
|
||||
(BIDI_IS_NUMBER(p) ? BIDI_TYPE_RTL : (p))
|
||||
|
||||
MG_EXPORT GUIAPI BOOL GetGlyphBIDIType (LOGFONT* log_font, Glyph32 glyph_value, Uint32 *bidi_type);
|
||||
/**
|
||||
* \fn BOOL GUIAPI GetGlyphBIDIType (LOGFONT* logfont,
|
||||
* Glyph32 glyph_value, Uint32 *bidi_type)
|
||||
* \brief Retriev the BIDI type of a glyph.
|
||||
*
|
||||
* This function retrieves the BIDI type of a glyph.
|
||||
*
|
||||
* \param logfont The logical font.
|
||||
* \param glyph_value The glyph value.
|
||||
* \param bidi_type The buffer storing the BIDI type of the glyph.
|
||||
*
|
||||
* \return TRUE if success, FALSE on failure.
|
||||
*
|
||||
* \sa GetGlyphInfo, GetGlyphType
|
||||
*/
|
||||
MG_EXPORT BOOL GUIAPI GetGlyphBIDIType (LOGFONT* log_font,
|
||||
Glyph32 glyph_value, Uint32 *bidi_type);
|
||||
|
||||
/** \fn int GUIAPI BIDIGetTextLogicalGlyphs(LOGFONT* log_font, \
|
||||
/**
|
||||
* \fn int GUIAPI BIDIGetTextLogicalGlyphs(LOGFONT* log_font, \
|
||||
const char* text, int text_len, Glyph32** glyphs, \
|
||||
GLYPHMAPINFO** glyphs_map)
|
||||
* \brief Get logical glyphs string of the text.
|
||||
|
||||
@@ -2,7 +2,7 @@ SUBDIRS = in-core
|
||||
|
||||
noinst_LTLIBRARIES = libfont.la
|
||||
|
||||
SRC_FILES = charset.c charset-arabic.c charset-bidi.c \
|
||||
SRC_FILES = charset.c charset-arabic.c charset-bidi.c unicode-comp.c \
|
||||
sysfont.c logfont.c devfont.c fontname.c \
|
||||
rawbitmap.c varbitmap.c qpf.c upf.c \
|
||||
fontcache.c freetype2.c font-engines.c\
|
||||
@@ -12,7 +12,8 @@ SRC_FILES = charset.c charset-arabic.c charset-bidi.c \
|
||||
bitmapfont.c scripteasy.c
|
||||
|
||||
HDR_FILES = charset.h rawbitmap.h varbitmap.h freetype2.h qpf.h se_minigui.h \
|
||||
upf.h bitmapfont.h gunichartables.h gunibreak.h unicode-bidi-tables.h
|
||||
upf.h bitmapfont.h unicode-bidi-tables.h \
|
||||
unicode-tables.h unicode-break.h unicode-decomp.h unicode-comp.h
|
||||
|
||||
EXTRA_DIST = convgbmap.c jisunimap.c $(SRC_FILES) $(HDR_FILES) \
|
||||
makefile.ng makefile.msvc
|
||||
|
||||
+2
-3
@@ -3486,9 +3486,8 @@ static Glyph32 utf8_char_glyph_value (const unsigned char* pre_mchar, int pre_le
|
||||
return wc;
|
||||
}
|
||||
|
||||
//#include "gunicode.h"
|
||||
#include "gunichartables.h"
|
||||
#include "gunibreak.h"
|
||||
#include "unicode-tables.h"
|
||||
#include "unicode-break.h"
|
||||
|
||||
#define ATTR_TABLE(Page) (((Page) <= UCHAR_TYPE_LAST_PAGE_PART1) \
|
||||
? attr_table_part1[Page] \
|
||||
|
||||
@@ -0,0 +1,485 @@
|
||||
/*
|
||||
* This file is part of MiniGUI, a mature cross-platform windowing
|
||||
* and Graphics User Interface (GUI) support system for embedded systems
|
||||
* and smart IoT devices.
|
||||
*
|
||||
* Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd.
|
||||
* Copyright (C) 1998~2002, WEI Yongming
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Or,
|
||||
*
|
||||
* As this program is a library, any link to this program must follow
|
||||
* GNU General Public License version 3 (GPLv3). If you cannot accept
|
||||
* GPLv3, you need to be licensed from FMSoft.
|
||||
*
|
||||
* If you have got a commercial license of this program, please use it
|
||||
* under the terms and conditions of the commercial license.
|
||||
*
|
||||
* For more information about the commercial license, please refer to
|
||||
* <http://www.minigui.com/en/about/licensing-policy/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "minigui.h"
|
||||
#include "gdi.h"
|
||||
|
||||
#ifdef _MGCHARSET_UNICODE
|
||||
|
||||
#include "unicode-decomp.h"
|
||||
#include "unicode-comp.h"
|
||||
|
||||
#define CC_PART1(Page, Char) \
|
||||
((combining_class_table_part1[Page] >= UCHAR_MAX_TABLE_INDEX) \
|
||||
? (combining_class_table_part1[Page] - UCHAR_MAX_TABLE_INDEX) \
|
||||
: (cclass_data[combining_class_table_part1[Page]][Char]))
|
||||
|
||||
#define CC_PART2(Page, Char) \
|
||||
((combining_class_table_part2[Page] >= UCHAR_MAX_TABLE_INDEX) \
|
||||
? (combining_class_table_part2[Page] - UCHAR_MAX_TABLE_INDEX) \
|
||||
: (cclass_data[combining_class_table_part2[Page]][Char]))
|
||||
|
||||
#define COMBINING_CLASS(Char) \
|
||||
(((Char) <= UCHAR_LAST_CHAR_PART1) \
|
||||
? CC_PART1 ((Char) >> 8, (Char) & 0xff) \
|
||||
: (((Char) >= 0xe0000 && (Char) <= UCHAR_LAST_CHAR) \
|
||||
? CC_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
|
||||
: 0))
|
||||
|
||||
int UCharCombiningClass (UChar32 uc)
|
||||
{
|
||||
return COMBINING_CLASS (uc);
|
||||
}
|
||||
|
||||
/* constants for hangul syllable [de]composition */
|
||||
#define SBase 0xAC00
|
||||
#define LBase 0x1100
|
||||
#define VBase 0x1161
|
||||
#define TBase 0x11A7
|
||||
#define LCount 19
|
||||
#define VCount 21
|
||||
#define TCount 28
|
||||
#define NCount (VCount * TCount)
|
||||
#define SCount (LCount * NCount)
|
||||
|
||||
void UCharCanonicalOrdering (UChar32 *string, int len)
|
||||
{
|
||||
int i;
|
||||
int swap = 1;
|
||||
|
||||
while (swap)
|
||||
{
|
||||
int last;
|
||||
swap = 0;
|
||||
last = COMBINING_CLASS (string[0]);
|
||||
for (i = 0; i < len - 1; ++i)
|
||||
{
|
||||
int next = COMBINING_CLASS (string[i + 1]);
|
||||
if (next != 0 && last > next)
|
||||
{
|
||||
int j;
|
||||
/* Percolate item leftward through string. */
|
||||
for (j = i + 1; j > 0; --j)
|
||||
{
|
||||
UChar32 t;
|
||||
if (COMBINING_CLASS (string[j - 1]) <= next)
|
||||
break;
|
||||
t = string[j];
|
||||
string[j] = string[j - 1];
|
||||
string[j - 1] = t;
|
||||
swap = 1;
|
||||
}
|
||||
/* We're re-entering the loop looking at the old
|
||||
character again. */
|
||||
next = last;
|
||||
}
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* http://www.unicode.org/unicode/reports/tr15/#Hangul
|
||||
* r should be null or have sufficient space. Calling with r == NULL will
|
||||
* only calculate the result_len; however, a buffer with space for three
|
||||
* characters will always be big enough. */
|
||||
static void decompose_hangul (UChar32 s, UChar32 *r, int *result_len)
|
||||
{
|
||||
int SIndex = s - SBase;
|
||||
int TIndex = SIndex % TCount;
|
||||
|
||||
if (r)
|
||||
{
|
||||
r[0] = LBase + SIndex / NCount;
|
||||
r[1] = VBase + (SIndex % NCount) / TCount;
|
||||
}
|
||||
|
||||
if (TIndex)
|
||||
{
|
||||
if (r)
|
||||
r[2] = TBase + TIndex;
|
||||
*result_len = 3;
|
||||
}
|
||||
else
|
||||
*result_len = 2;
|
||||
}
|
||||
|
||||
/* returns a pointer to a null-terminated UTF-8 string */
|
||||
static const unsigned char * find_decomposition (UChar32 ch, BOOL compat)
|
||||
{
|
||||
int start = 0;
|
||||
int end = TABLESIZE (decomp_table);
|
||||
|
||||
if (ch >= decomp_table[start].ch &&
|
||||
ch <= decomp_table[end - 1].ch) {
|
||||
while (TRUE) {
|
||||
int half = (start + end) / 2;
|
||||
if (ch == decomp_table[half].ch) {
|
||||
int offset;
|
||||
|
||||
if (compat) {
|
||||
offset = decomp_table[half].compat_offset;
|
||||
if (offset == UCHAR_NOT_PRESENT_OFFSET)
|
||||
offset = decomp_table[half].canon_offset;
|
||||
}
|
||||
else {
|
||||
offset = decomp_table[half].canon_offset;
|
||||
if (offset == UCHAR_NOT_PRESENT_OFFSET)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &(decomp_expansion_string[offset]);
|
||||
}
|
||||
else if (half == start)
|
||||
break;
|
||||
else if (ch > decomp_table[half].ch)
|
||||
start = half;
|
||||
else
|
||||
end = half;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* L,V => LV and LV,T => LVT */
|
||||
static BOOL combine_hangul (UChar32 a, UChar32 b, UChar32 *result)
|
||||
{
|
||||
int LIndex = a - LBase;
|
||||
int SIndex = a - SBase;
|
||||
|
||||
int VIndex = b - VBase;
|
||||
int TIndex = b - TBase;
|
||||
|
||||
if (0 <= LIndex && LIndex < LCount
|
||||
&& 0 <= VIndex && VIndex < VCount) {
|
||||
*result = SBase + (LIndex * VCount + VIndex) * TCount;
|
||||
return TRUE;
|
||||
}
|
||||
else if (0 <= SIndex && SIndex < SCount && (SIndex % TCount) == 0
|
||||
&& 0 < TIndex && TIndex < TCount) {
|
||||
*result = a + TIndex;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define CI(Page, Char) \
|
||||
((compose_table[Page] >= UCHAR_MAX_TABLE_INDEX) \
|
||||
? (compose_table[Page] - UCHAR_MAX_TABLE_INDEX) \
|
||||
: (compose_data[compose_table[Page]][Char]))
|
||||
|
||||
#define COMPOSE_INDEX(Char) \
|
||||
(((Char >> 8) > (COMPOSE_TABLE_LAST)) ? 0 : CI((Char) >> 8, (Char) & 0xff))
|
||||
|
||||
static BOOL combine (UChar32 a, UChar32 b, UChar32 *result)
|
||||
{
|
||||
unsigned short index_a, index_b;
|
||||
|
||||
if (combine_hangul (a, b, result))
|
||||
return TRUE;
|
||||
|
||||
index_a = COMPOSE_INDEX(a);
|
||||
|
||||
if (index_a >= COMPOSE_FIRST_SINGLE_START && index_a < COMPOSE_SECOND_START)
|
||||
{
|
||||
if (b == compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][0])
|
||||
{
|
||||
*result = compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][1];
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
index_b = COMPOSE_INDEX(b);
|
||||
|
||||
if (index_b >= COMPOSE_SECOND_SINGLE_START)
|
||||
{
|
||||
if (a == compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][0])
|
||||
{
|
||||
*result = compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][1];
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (index_a >= COMPOSE_FIRST_START && index_a < COMPOSE_FIRST_SINGLE_START &&
|
||||
index_b >= COMPOSE_SECOND_START && index_b < COMPOSE_SECOND_SINGLE_START)
|
||||
{
|
||||
UChar32 res = compose_array[index_a - COMPOSE_FIRST_START][index_b - COMPOSE_SECOND_START];
|
||||
|
||||
if (res)
|
||||
{
|
||||
*result = res;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL decompose_hangul_step (UChar32 ch, UChar32 *a, UChar32 *b)
|
||||
{
|
||||
int SIndex, TIndex;
|
||||
|
||||
if (ch < SBase || ch >= SBase + SCount)
|
||||
return FALSE; /* not a hangul syllable */
|
||||
|
||||
SIndex = ch - SBase;
|
||||
TIndex = SIndex % TCount;
|
||||
|
||||
if (TIndex) {
|
||||
/* split LVT -> LV,T */
|
||||
*a = ch - TIndex;
|
||||
*b = TBase + TIndex;
|
||||
}
|
||||
else {
|
||||
/* split LV -> L,V */
|
||||
*a = LBase + SIndex / NCount;
|
||||
*b = VBase + (SIndex % NCount) / TCount;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL UCharDecompose (UChar32 ch, UChar32 *a, UChar32 *b)
|
||||
{
|
||||
int start = 0;
|
||||
int end = TABLESIZE (decomp_step_table);
|
||||
|
||||
if (decompose_hangul_step (ch, a, b))
|
||||
return TRUE;
|
||||
|
||||
/* TODO use bsearch() */
|
||||
if (ch >= decomp_step_table[start].ch &&
|
||||
ch <= decomp_step_table[end - 1].ch)
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
int half = (start + end) / 2;
|
||||
const decomposition_step *p = &(decomp_step_table[half]);
|
||||
if (ch == p->ch)
|
||||
{
|
||||
*a = p->a;
|
||||
*b = p->b;
|
||||
return TRUE;
|
||||
}
|
||||
else if (half == start)
|
||||
break;
|
||||
else if (ch > p->ch)
|
||||
start = half;
|
||||
else
|
||||
end = half;
|
||||
}
|
||||
}
|
||||
|
||||
*a = ch;
|
||||
*b = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL UCharCompose (UChar32 a, UChar32 b, UChar32 *ch)
|
||||
{
|
||||
if (combine (a, b, ch))
|
||||
return TRUE;
|
||||
|
||||
*ch = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define UTF8_COMPUTE(Char, Mask, Len) \
|
||||
if (Char < 128) \
|
||||
{ \
|
||||
Len = 1; \
|
||||
Mask = 0x7f; \
|
||||
} \
|
||||
else if ((Char & 0xe0) == 0xc0) \
|
||||
{ \
|
||||
Len = 2; \
|
||||
Mask = 0x1f; \
|
||||
} \
|
||||
else if ((Char & 0xf0) == 0xe0) \
|
||||
{ \
|
||||
Len = 3; \
|
||||
Mask = 0x0f; \
|
||||
} \
|
||||
else if ((Char & 0xf8) == 0xf0) \
|
||||
{ \
|
||||
Len = 4; \
|
||||
Mask = 0x07; \
|
||||
} \
|
||||
else if ((Char & 0xfc) == 0xf8) \
|
||||
{ \
|
||||
Len = 5; \
|
||||
Mask = 0x03; \
|
||||
} \
|
||||
else if ((Char & 0xfe) == 0xfc) \
|
||||
{ \
|
||||
Len = 6; \
|
||||
Mask = 0x01; \
|
||||
} \
|
||||
else \
|
||||
Len = -1;
|
||||
|
||||
#define UTF8_LENGTH(Char) \
|
||||
((Char) < 0x80 ? 1 : \
|
||||
((Char) < 0x800 ? 2 : \
|
||||
((Char) < 0x10000 ? 3 : \
|
||||
((Char) < 0x200000 ? 4 : \
|
||||
((Char) < 0x4000000 ? 5 : 6)))))
|
||||
|
||||
|
||||
#define UTF8_GET(Result, Chars, Count, Mask, Len) \
|
||||
(Result) = (Chars)[0] & (Mask); \
|
||||
for ((Count) = 1; (Count) < (Len); ++(Count)) \
|
||||
{ \
|
||||
if (((Chars)[(Count)] & 0xc0) != 0x80) \
|
||||
{ \
|
||||
(Result) = -1; \
|
||||
break; \
|
||||
} \
|
||||
(Result) <<= 6; \
|
||||
(Result) |= ((Chars)[(Count)] & 0x3f); \
|
||||
}
|
||||
|
||||
static UChar32 utf8_to_uchar32 (const unsigned char *p)
|
||||
{
|
||||
int i, mask = 0, len;
|
||||
UChar32 result;
|
||||
unsigned char c = (unsigned char) *p;
|
||||
|
||||
UTF8_COMPUTE (c, mask, len);
|
||||
if (len == -1)
|
||||
return (UChar32)-1;
|
||||
UTF8_GET (result, p, i, mask, len);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define UNICODE_VALID(Char) \
|
||||
((Char) < 0x110000 && \
|
||||
(((Char) & 0xFFFFF800) != 0xD800))
|
||||
|
||||
static const unsigned char utf8_skip_data[256] = {
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
|
||||
};
|
||||
|
||||
#define utf8_next_char(p) ((p) + utf8_skip_data[*(p)])
|
||||
|
||||
static int utf8_strlen (const unsigned char *p, int max)
|
||||
{
|
||||
int len = 0;
|
||||
const unsigned char *start = p;
|
||||
if (p == NULL && max == 0)
|
||||
return 0;
|
||||
|
||||
if (max < 0) {
|
||||
while (*p) {
|
||||
p = utf8_next_char (p);
|
||||
++len;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (max == 0 || !*p)
|
||||
return 0;
|
||||
|
||||
p = utf8_next_char (p);
|
||||
|
||||
while (p - start < max && *p) {
|
||||
++len;
|
||||
p = utf8_next_char (p);
|
||||
}
|
||||
|
||||
/* only do the last len increment if we got a complete
|
||||
* char (don't count partial chars)
|
||||
*/
|
||||
if (p - start <= max)
|
||||
++len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int UCharFullyDecompose (UChar32 ch, BOOL compat, UChar32 *result, int result_len)
|
||||
{
|
||||
const unsigned char *decomp;
|
||||
const unsigned char *p;
|
||||
|
||||
/* Hangul syllable */
|
||||
if (ch >= SBase && ch < SBase + SCount) {
|
||||
int len, i;
|
||||
UChar32 buffer[3];
|
||||
decompose_hangul (ch, result ? buffer : NULL, &len);
|
||||
if (result)
|
||||
for (i = 0; i < len && i < result_len; i++)
|
||||
result[i] = buffer[i];
|
||||
return len;
|
||||
}
|
||||
else if ((decomp = find_decomposition (ch, compat)) != NULL)
|
||||
{
|
||||
/* Found it. */
|
||||
int len, i;
|
||||
|
||||
len = utf8_strlen (decomp, -1);
|
||||
|
||||
for (p = decomp, i = 0; i < len && i < result_len; p = utf8_next_char (p), i++)
|
||||
result[i] = utf8_to_uchar32 (p);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* Does not decompose */
|
||||
if (result && result_len >= 1)
|
||||
*result = ch;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* _MGCHARSET_UNICODE */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+34
-15
@@ -141,6 +141,19 @@ Glyph32 GUIAPI GetGlyphShape (LOGFONT* logfont, const char* mchar,
|
||||
return glyph_value;
|
||||
}
|
||||
|
||||
BOOL GUIAPI GetMirrorGlyph (LOGFONT* logfont, Glyph32 gv,
|
||||
Glyph32* mirrored)
|
||||
{
|
||||
*mirrored = INV_GLYPH_VALUE;
|
||||
|
||||
DEVFONT* devfont = SELECT_DEVFONT(logfont, gv);
|
||||
if (devfont->charset_ops->bidi_mirror_glyph) {
|
||||
return devfont->charset_ops->bidi_mirror_glyph(gv, mirrored);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value,
|
||||
int* adv_x, int* adv_y)
|
||||
{
|
||||
@@ -176,24 +189,30 @@ int GUIAPI DrawGlyph (HDC hdc, int x, int y, Glyph32 glyph_value,
|
||||
return advance;
|
||||
}
|
||||
|
||||
unsigned int GUIAPI GetGlyphType (LOGFONT* logfont, Glyph32 glyph_value)
|
||||
{
|
||||
/* get the relative device font */
|
||||
DEVFONT* devfont = SELECT_DEVFONT(logfont, glyph_value);
|
||||
glyph_value = REAL_GLYPH (glyph_value);
|
||||
return devfont->charset_ops->glyph_type (glyph_value);
|
||||
}
|
||||
|
||||
int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value,
|
||||
GLYPHINFO* glyph_info)
|
||||
{
|
||||
int advance = 0;
|
||||
int pitch = 0;
|
||||
|
||||
/* get the relative device font*/
|
||||
/* get the relative device font */
|
||||
DEVFONT* devfont = SELECT_DEVFONT(logfont, glyph_value);
|
||||
glyph_value = REAL_GLYPH (glyph_value);
|
||||
|
||||
/*get glyph type*/
|
||||
/* get glyph type */
|
||||
if (glyph_info->mask & GLYPH_INFO_TYPE)
|
||||
glyph_info->glyph_type = devfont->charset_ops->glyph_type (glyph_value);
|
||||
|
||||
/*get glyph type*/
|
||||
/* get glyph type */
|
||||
if (glyph_info->mask & GLYPH_INFO_BIDI_TYPE) {
|
||||
if (devfont->charset_ops->bidi_glyph_type) {
|
||||
glyph_info->bidi_glyph_type = devfont->charset_ops->bidi_glyph_type (glyph_value);
|
||||
glyph_info->bidi_glyph_type
|
||||
= devfont->charset_ops->bidi_glyph_type (glyph_value);
|
||||
}
|
||||
else {
|
||||
glyph_info->bidi_glyph_type = BIDI_TYPE_INVALID;
|
||||
@@ -212,6 +231,7 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value,
|
||||
(BBOX*)(&glyph_info->bbox_x));
|
||||
}
|
||||
|
||||
/* get glyph bitmap info */
|
||||
if (glyph_info->mask & GLYPH_INFO_BMP) {
|
||||
DWORD bmptype = devfont->font_ops->get_glyph_bmptype (logfont, devfont);
|
||||
glyph_info->bmp_type = bmptype & DEVFONTGLYPHTYPE_MASK_BMPTYPE;
|
||||
@@ -219,9 +239,8 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value,
|
||||
switch (glyph_info->bmp_type) {
|
||||
case GLYPHBMP_TYPE_MONO:
|
||||
glyph_info->bits = devfont->font_ops->get_glyph_monobitmap (
|
||||
logfont, devfont, glyph_value, &pitch, NULL);
|
||||
glyph_info->bmp_pitch = pitch;
|
||||
glyph_info->bmp_size = pitch * glyph_info->bbox_h;
|
||||
logfont, devfont, glyph_value, &glyph_info->bmp_pitch, NULL);
|
||||
glyph_info->bmp_size = glyph_info->bmp_pitch * glyph_info->bbox_h;
|
||||
break;
|
||||
|
||||
case GLYPHBMP_TYPE_GREY:
|
||||
@@ -247,7 +266,7 @@ int GUIAPI GetGlyphInfo (LOGFONT* logfont, Glyph32 glyph_value,
|
||||
}
|
||||
}
|
||||
|
||||
return advance;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GUIAPI GetGlyphBitmap (LOGFONT* logfont, const char* mchar,
|
||||
@@ -272,7 +291,7 @@ void GUIAPI GetGlyphBitmap (LOGFONT* logfont, const char* mchar,
|
||||
static int mult (fixed op1, fixed op2)
|
||||
{
|
||||
long s = op2;
|
||||
if(s < 0)
|
||||
if (s < 0)
|
||||
op2 = -op2;
|
||||
{
|
||||
long op1_hi = (op1 >> 16)& 0xffff;
|
||||
@@ -283,9 +302,9 @@ static int mult (fixed op1, fixed op2)
|
||||
long prod_hi = op1_hi * op2_hi + ((cross_prod >> 16) & 0xffff);
|
||||
long prod_lo = op1_lo * op2_lo + ((cross_prod << 16) & 0xffff0000);
|
||||
|
||||
prod_hi +=((prod_lo& 0x80000000)>>31);
|
||||
if(s <0)
|
||||
prod_hi =-prod_hi;
|
||||
prod_hi += ((prod_lo& 0x80000000)>>31);
|
||||
if (s < 0)
|
||||
prod_hi = -prod_hi;
|
||||
|
||||
return (int)prod_hi;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user