add UCharCanonicalOrdering and others for composition and decomposition

This commit is contained in:
Vincent Wei
2019-01-17 18:45:22 +08:00
parent 8cd6b037ec
commit 03eac03c8c
11 changed files with 15369 additions and 30 deletions
+14 -3
View File
@@ -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
View File
@@ -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.
+3 -2
View File
@@ -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
View File
@@ -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] \
+485
View File
@@ -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
View File
@@ -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;
}