From 9945cd25a5dcf8ef88e24e176a79669a81a3675a Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 28 Aug 2018 18:38:20 +0800 Subject: [PATCH 1/9] BIDI flag for DC --- include/gdi.h | 37 +++++++++++++++++++++++++++---------- src/include/dc.h | 3 +++ src/newgdi/tabbedtextout.c | 5 ++--- src/newgdi/textout.c | 5 ++--- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index 483b6a7c..4c79a77b 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -2009,20 +2009,26 @@ MG_EXPORT void GUIAPI DeleteSecondaryDC (HWND hwnd); #define DC_ATTR_TEXT_ALIGN 10 +#define DC_ATTR_BIDI_ENABLED 11 +#define DC_ATTR_BIDI_FIRSTCH_TYPE 12 + #define BIDI_CHAR_TYPE_INIT 0 + #define BIDI_CHAR_TYPE_LTR 1 + #define BIDI_CHAR_TYPE_RTL 2 + #ifdef _MGHAVE_ADV_2DAPI -#define DC_ATTR_PEN_TYPE 11 -#define DC_ATTR_PEN_CAP_STYLE 12 -#define DC_ATTR_PEN_JOIN_STYLE 13 -#define DC_ATTR_PEN_WIDTH 14 +#define DC_ATTR_PEN_TYPE 13 +#define DC_ATTR_PEN_CAP_STYLE 14 +#define DC_ATTR_PEN_JOIN_STYLE 15 +#define DC_ATTR_PEN_WIDTH 16 -#define DC_ATTR_BRUSH_TYPE 15 +#define DC_ATTR_BRUSH_TYPE 17 -#define NR_DC_ATTRS 16 +#define NR_DC_ATTRS 18 #else -#define NR_DC_ATTRS 11 +#define NR_DC_ATTRS 13 #endif @@ -2064,9 +2070,12 @@ MG_EXPORT void GUIAPI DeleteSecondaryDC (HWND hwnd); * Spacing bellow line for the DC. * - DC_ATTR_MAP_MODE\n * mode of a DC. - * - DC_ATTR_TEXT_ALIGN\n + * - DC_ATTR_TEXT_ALIGN\n * Text-alignment flags of a DC. - * + * - DC_ATTR_BIDI_ENABLED\n + * Is BIDI enabled. + * - DC_ATTR_BIDI_FIRSTCH_TYPE\n + * The first character type, on of BIDI_CHAR_TYPE_INIT, BIDI_CHAR_TYPE_LTR, or BIDI_CHAR_TYPE_RTL. * \return The attribute value. * * \sa SetDCAttr @@ -7008,7 +7017,15 @@ MG_EXPORT int GUIAPI GetTabbedTextExtent (HDC hdc, * \sa GetTextAlign */ #define SetTextAlign(hdc, ta_flags) \ - SetDCAttr (hdc, DC_ATTR_TEXT_ALIGN, (DWORD)ta_flags) + SetDCAttr (hdc, DC_ATTR_TEXT_ALIGN, (DWORD)ta_flags) + +#define GetBIDIFlag(hdc) GetDCAttr (hdc, DC_ATTR_BIDI_ENABLED) +#define SetBIDIFlag(hdc, bidi) \ + SetDCAttr (hdc, DC_ATTR_BIDI_ENABLED, (DWORD)bidi) + +#define GetBIDIFirstChType(hdc) GetDCAttr (hdc, DC_ATTR_BIDI_FIRSTCH_TYPE) +#define SetBIDIFirstChType(hdc, type) \ + SetDCAttr (hdc, DC_ATTR_BIDI_FIRSTCH_TYPE, (DWORD)type) /** * \fn int GUIAPI TextOutLen (HDC hdc, int x, int y, \ diff --git a/src/include/dc.h b/src/include/dc.h index f00769f3..fa8b36ae 100644 --- a/src/include/dc.h +++ b/src/include/dc.h @@ -166,6 +166,9 @@ struct tagDC int ta_flags; /* Text alignment flags */ + int bidi_flag; /* BIDI enable flag */ + int bidi_firstch_type; /* BIDI first char type */ + #ifdef _MGHAVE_ADV_2DAPI /* pen attributes */ int pen_type; diff --git a/src/newgdi/tabbedtextout.c b/src/newgdi/tabbedtextout.c index cf086a99..edbb51b6 100644 --- a/src/newgdi/tabbedtextout.c +++ b/src/newgdi/tabbedtextout.c @@ -529,10 +529,9 @@ int GUIAPI GetTabbedTextExtentPoint (HDC hdc, const char* text, /* set size to zero first */ size->cx = size->cy = 0; - /* FIXME: use HDC property for BIDI enable or not - if (mbc_devfont && mbc_devfont->charset_ops->bidi_reorder) + /* This function does not support BIDI */ + if (mbc_devfont && pdc->bidi_flag && mbc_devfont->charset_ops->bidi_glyph_type) return -1; - */ _gdi_start_new_line (pdc); diff --git a/src/newgdi/textout.c b/src/newgdi/textout.c index 4aa51f7a..116d0b1d 100644 --- a/src/newgdi/textout.c +++ b/src/newgdi/textout.c @@ -462,10 +462,9 @@ int GUIAPI GetTextExtentPoint (HDC hdc, const char* text, int len, /* set size to zero first */ size->cx = size->cy = 0; - /* FIXME: use HDC property for BIDI enable or not - if (mbc_devfont && mbc_devfont->charset_ops->bidi_reorder) + /* This function does not support BIDI */ + if (mbc_devfont && pdc->bidi_flag && mbc_devfont->charset_ops->bidi_glyph_type) return -1; - */ _gdi_start_new_line(pdc); From ae532f03fa145cc4e8b2451829fb23fb182c9e1e Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Wed, 29 Aug 2018 20:03:20 +0800 Subject: [PATCH 2/9] add GetGlyphBIDIType and BidiCharType -> Uint32 --- include/gdi.h | 194 ++++++++++++++++++++++++++++++++ src/font/charset-arabic.c | 2 +- src/font/charset-bidi.c | 39 ++++--- src/font/charset.c | 2 +- src/font/unicode-bidi-tables.h | 6 +- src/include/bidi.h | 195 +-------------------------------- src/newgdi/bidi.c | 23 ++-- src/sysres/font/makefile.ng | 0 8 files changed, 240 insertions(+), 221 deletions(-) mode change 100755 => 100644 src/sysres/font/makefile.ng diff --git a/include/gdi.h b/include/gdi.h index 4c79a77b..a0d7392f 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -8827,6 +8827,200 @@ MG_EXPORT int GUIAPI GetGlyphsExtent(HDC hdc, Glyph32* glyphs, int nr_glyphs, MG_EXPORT int GUIAPI GetGlyphsExtentPoint(HDC hdc, Glyph32* glyphs, int nr_glyphs, int max_extent, SIZE* size); +/* + * Define some bit masks, that character types are based on, each one has + * only one bit on. + */ + +#define BIDI_MASK_RTL 0x00000001L /* Is right to left */ +#define BIDI_MASK_ARABIC 0x00000002L /* Is arabic */ + +/* Each char can be only one of the three following. */ +#define BIDI_MASK_STRONG 0x00000010L /* Is strong */ +#define BIDI_MASK_WEAK 0x00000020L /* Is weak */ +#define BIDI_MASK_NEUTRAL 0x00000040L /* Is neutral */ +#define BIDI_MASK_SENTINEL 0x00000080L /* Is sentinel: SOT, EOT */ + +/* Each char can be only one of the five following. */ +#define BIDI_MASK_LETTER 0x00000100L /* Is letter: L, R, AL */ +#define BIDI_MASK_NUMBER 0x00000200L /* Is number: EN, AN */ +#define BIDI_MASK_NUMSEPTER 0x00000400L /* Is number separator or terminator: ES, ET, CS */ +#define BIDI_MASK_SPACE 0x00000800L /* Is space: BN, BS, SS, WS */ +#define BIDI_MASK_EXPLICIT 0x00001000L /* Is expilict mark: LRE, RLE, LRO, RLO, PDF */ + +/* Can be on only if BIDI_MASK_SPACE is also on. */ +#define BIDI_MASK_SEPARATOR 0x00002000L /* Is test separator: BS, SS */ +/* Can be on only if BIDI_MASK_EXPLICIT is also on. */ +#define BIDI_MASK_OVERRIDE 0x00004000L /* Is explicit override: LRO, RLO */ + +#define BIDI_MASK_ES 0x00010000L +#define BIDI_MASK_ET 0x00020000L +#define BIDI_MASK_CS 0x00040000L + +#define BIDI_MASK_NSM 0x00080000L +#define BIDI_MASK_BN 0x00100000L + +#define BIDI_MASK_BS 0x00200000L +#define BIDI_MASK_SS 0x00400000L +#define BIDI_MASK_WS 0x00800000L + +/* + * Define values for Bidi char type + */ + +/* Strong left to right */ +#define BIDI_TYPE_LTR (BIDI_MASK_STRONG + BIDI_MASK_LETTER) + +/* Right to left characters */ +#define BIDI_TYPE_RTL (BIDI_MASK_STRONG + BIDI_MASK_LETTER \ + + BIDI_MASK_RTL) + +/* Arabic characters */ +#define BIDI_TYPE_AL (BIDI_MASK_STRONG + BIDI_MASK_LETTER \ + + BIDI_MASK_RTL + BIDI_MASK_ARABIC) + +/* Left-To-Right embedding */ +#define BIDI_TYPE_LRE (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT) + +/* Right-To-Left embedding */ +#define BIDI_TYPE_RLE (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ + + BIDI_MASK_RTL) + +/* Left-To-Right override */ +#define BIDI_TYPE_LRO (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ + + BIDI_MASK_OVERRIDE) + +/* Right-To-Left override */ +#define BIDI_TYPE_RLO (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ + + BIDI_MASK_RTL + BIDI_MASK_OVERRIDE) + +/* Pop directional override */ +#define BIDI_TYPE_PDF (BIDI_MASK_WEAK + BIDI_MASK_EXPLICIT) + +/* European digit */ +#define BIDI_TYPE_EN (BIDI_MASK_WEAK + BIDI_MASK_NUMBER) + +/* Arabic digit */ +#define BIDI_TYPE_AN (BIDI_MASK_WEAK + BIDI_MASK_NUMBER \ + + BIDI_MASK_ARABIC) + +/* European number separator */ +#define BIDI_TYPE_ES (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ + + BIDI_MASK_ES) + +/* European number terminator */ +#define BIDI_TYPE_ET (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ + + BIDI_MASK_ET) + +/* Common Separator */ +#define BIDI_TYPE_CS (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ + + BIDI_MASK_CS) + +/* Non spacing mark */ +#define BIDI_TYPE_NSM (BIDI_MASK_WEAK + BIDI_MASK_NSM) + +/* Boundary neutral */ +#define BIDI_TYPE_BN (BIDI_MASK_WEAK + BIDI_MASK_SPACE \ + + BIDI_MASK_BN) + +/* Block separator */ +#define BIDI_TYPE_BS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ + + BIDI_MASK_SEPARATOR + BIDI_MASK_BS) + +/* Segment separator */ +#define BIDI_TYPE_SS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ + + BIDI_MASK_SEPARATOR + BIDI_MASK_SS) +/* Whitespace */ +#define BIDI_TYPE_WS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ + + BIDI_MASK_WS) + +/* Other Neutral */ +#define BIDI_TYPE_ON (BIDI_MASK_NEUTRAL) + +/* The following are used to identify the paragraph direction, + types L, R, N are not used internally anymore, and recommended to use + LTR, RTL and ON instead, didn't removed because of compatability. */ + +#define BIDI_TYPE_L (BIDI_TYPE_LTR) +#define BIDI_TYPE_R (BIDI_TYPE_RTL) +#define BIDI_TYPE_N (BIDI_TYPE_ON) +/* Weak left to right */ +#define BIDI_TYPE_WL (BIDI_MASK_WEAK) +/* Weak right to left */ +#define BIDI_TYPE_WR (BIDI_MASK_WEAK + BIDI_MASK_RTL) + +/* The following are only used internally */ + +/* Start of text */ +#define BIDI_TYPE_SOT (BIDI_MASK_SENTINEL) +/* End of text */ +#define BIDI_TYPE_EOT (BIDI_MASK_SENTINEL + BIDI_MASK_RTL) + +/* Is private-use value? */ +#define BIDI_TYPE_PRIVATE(p) ((p) < 0) + +/* Return the direction of the level number, BIDI_TYPE_LTR for even and + BIDI_TYPE_RTL for odds. */ +#define BIDI_LEVEL_TO_DIR(lev) (BIDI_TYPE_LTR | (lev & 1)) + +/* Return the minimum level of the direction, 0 for BIDI_TYPE_LTR and + 1 for BIDI_TYPE_RTL and BIDI_TYPE_AL. */ +#define BIDI_DIR_TO_LEVEL(dir) ((BYTE)(dir & 1)) + +/* Is right to left? */ +#define BIDI_IS_RTL(p) ((p) & BIDI_MASK_RTL) +/* Is arabic? */ +#define BIDI_IS_ARABIC(p) ((p) & BIDI_MASK_ARABIC) + +/* Is strong? */ +#define BIDI_IS_STRONG(p) ((p) & BIDI_MASK_STRONG) +/* Is weak? */ +#define BIDI_IS_WEAK(p) ((p) & BIDI_MASK_WEAK) +/* Is neutral? */ +#define BIDI_IS_NEUTRAL(p) ((p) & BIDI_MASK_NEUTRAL) +/* Is sentinel? */ +#define BIDI_IS_SENTINEL(p) ((p) & BIDI_MASK_SENTINEL) + +/* Is letter: L, R, AL? */ +#define BIDI_IS_LETTER(p) ((p) & BIDI_MASK_LETTER) +/* Is number: EN, AN? */ +#define BIDI_IS_NUMBER(p) ((p) & BIDI_MASK_NUMBER) +/* Is number separator or terminator: ES, ET, CS? */ +#define BIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR(p) \ + ((p) & BIDI_MASK_NUMSEPTER) + +/* Is space: BN, BS, SS, WS? */ +#define BIDI_IS_SPACE(p) ((p) & BIDI_MASK_SPACE) +/* Is explicit mark: LRE, RLE, LRO, RLO, PDF? */ +#define BIDI_IS_EXPLICIT(p) ((p) & BIDI_MASK_EXPLICIT) + +/* Is test separator: BS, SS? */ +#define BIDI_IS_SEPARATOR(p) ((p) & BIDI_MASK_SEPARATOR) + +/* Is explicit override: LRO, RLO? */ +#define BIDI_IS_OVERRIDE(p) ((p) & BIDI_MASK_OVERRIDE) + +/* Some more: */ + +/* Is left to right letter: LTR? */ +#define BIDI_IS_LTR_LETTER(p) \ + ((p) & (BIDI_MASK_LETTER | BIDI_MASK_RTL) == BIDI_MASK_LETTER) + +/* Is right to left letter: RTL, AL? */ +#define BIDI_IS_RTL_LETTER(p) \ + ((p) & (BIDI_MASK_LETTER | BIDI_MASK_RTL) \ + == (BIDI_MASK_LETTER | BIDI_MASK_RTL)) + +/* Is ES or CS: ES, CS? */ +#define BIDI_IS_ES_OR_CS(p) \ + ((p) & (BIDI_MASK_ES | BIDI_MASK_CS)) + +/* Change numbers: EN, AN to RTL. */ +#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 int GUIAPI BIDIGetTextLogicalGlyphs(LOGFONT* log_font, \ const char* text, int text_len, Glyph32** glyphs, \ GLYPHMAPINFO** glyphs_map) diff --git a/src/font/charset-arabic.c b/src/font/charset-arabic.c index 5f30b7b6..909400e1 100644 --- a/src/font/charset-arabic.c +++ b/src/font/charset-arabic.c @@ -468,7 +468,7 @@ static unsigned int iso8859_6_glyph_type (Glyph32 glyph_value) return ch_type; } -static BidiCharType __mg_iso8859_68x_type[] = { +static Uint32 __mg_iso8859_68x_type[] = { /*0x00~0x0f*/ BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, diff --git a/src/font/charset-bidi.c b/src/font/charset-bidi.c index 43e4a18e..17b0f615 100644 --- a/src/font/charset-bidi.c +++ b/src/font/charset-bidi.c @@ -63,14 +63,14 @@ struct _TYPERUN struct _TYPERUN *prev; struct _TYPERUN *next; - BidiCharType type; /* char type. */ + Uint32 type; /* char type. */ int pos, len; /* run start position、run len.*/ BYTE level; /* Embedding level. */ }; #ifdef BIDI_DEBUG -static char bidi_type_name(BidiCharType c) +static char bidi_type_name(Uint32 c) { switch (c){ case BIDI_TYPE_LTR: return 'L'; @@ -251,7 +251,7 @@ static TYPERUN* get_runtype_link (const CHARSETOPS* charset_ops, Glyph32* glyphs /* 1.Find base level */ -static void bidi_resolveParagraphs(TYPERUN **ptype_rl_list, BidiCharType* pbase_dir, BYTE* pbase_level) +static void bidi_resolveParagraphs(TYPERUN **ptype_rl_list, Uint32* pbase_dir, BYTE* pbase_level) { TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL; DBGLOG("\n1:Finding the base level\n"); @@ -273,7 +273,7 @@ static void bidi_resolveParagraphs(TYPERUN **ptype_rl_list, BidiCharType* pbase_ /* 2.Resolving Explicit levels. * now nothing need to do.*/ -static void bidi_resolveExplicit (TYPERUN **ptype_rl_list, BidiCharType base_dir) +static void bidi_resolveExplicit (TYPERUN **ptype_rl_list, Uint32 base_dir) { TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL; DBGLOG("\n2:Resolving weak types\n"); @@ -286,10 +286,10 @@ static void bidi_resolveExplicit (TYPERUN **ptype_rl_list, BidiCharType base_dir } /* 3.Resolving weak types */ -static void bidi_resolveWeak(TYPERUN **ptype_rl_list, BidiCharType base_dir) +static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir) { TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL; - BidiCharType last_strong, prev_type_org; + Uint32 last_strong, prev_type_org; BOOL w4; DBGLOG("\n3:Resolving weak types\n"); @@ -297,7 +297,7 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, BidiCharType base_dir) for (pp = type_rl_list->next; pp->next; pp = pp->next) { - BidiCharType prev_type, this_type, next_type; + Uint32 prev_type, this_type, next_type; prev_type = TYPE(pp->prev); this_type = TYPE(pp); @@ -338,7 +338,7 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, BidiCharType base_dir) for (pp = type_rl_list->next; pp->next; pp = pp->next) { - BidiCharType prev_type, this_type, next_type; + Uint32 prev_type, this_type, next_type; prev_type = TYPE(pp->prev); this_type = TYPE(pp); @@ -409,13 +409,13 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, BidiCharType 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, BidiCharType base_bir) +static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir) { TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL; DBGLOG ("\n4:Resolving neutral types\n"); for (pp = type_rl_list->next; pp->next; pp = pp->next) { - BidiCharType prev_type, this_type, next_type; + Uint32 prev_type, this_type, next_type; prev_type = TYPE(pp->prev); this_type = TYPE(pp); @@ -446,7 +446,7 @@ static int bidi_resolveImplicit(TYPERUN **ptype_rl_list, int base_level) DBGLOG ("\n5:Resolving implicit levels\n"); for (pp = type_rl_list->next; pp->next; pp = pp->next){ - BidiCharType this_type; + Uint32 this_type; int level; this_type = TYPE(pp); @@ -536,7 +536,7 @@ static void bidi_resolve_string (const CHARSETOPS* charset_ops, Glyph32* glyphs, TYPERUN **ptype_rl_list, BYTE *pmax_level) { BYTE base_level = 0; - BidiCharType base_dir = BIDI_TYPE_L; + Uint32 base_dir = BIDI_TYPE_L; TYPERUN *type_rl_list = NULL; /* split the text to some runs. */ @@ -699,10 +699,10 @@ Glyph32* __mg_charset_bidi_glyphs_reorder (const CHARSETOPS* charset_ops, Glyph3 return glyphs; } -BidiCharType __mg_charset_bidi_str_base_dir (const CHARSETOPS* charset_ops, Glyph32* glyphs, int len) +Uint32 __mg_charset_bidi_str_base_dir (const CHARSETOPS* charset_ops, Glyph32* glyphs, int len) { BYTE base_level = 0; - BidiCharType base_dir = BIDI_TYPE_L; + Uint32 base_dir = BIDI_TYPE_L; TYPERUN *type_rl_list = NULL; /* split the text to some runs. */ @@ -717,3 +717,14 @@ BidiCharType __mg_charset_bidi_str_base_dir (const CHARSETOPS* charset_ops, Glyp return base_dir; } +BOOL GetGlyphBIDIType (LOGFONT* log_font, Glyph32 glyph_value, Uint32 *bidi_type) +{ + DEVFONT* mbc_devfont = log_font->mbc_devfont; + + if (mbc_devfont == NULL || mbc_devfont->charset_ops->bidi_glyph_type == NULL) + return FALSE; + + *bidi_type = mbc_devfont->charset_ops->bidi_glyph_type (glyph_value); + return TRUE; +} + diff --git a/src/font/charset.c b/src/font/charset.c index 5d27cb66..647b4f36 100644 --- a/src/font/charset.c +++ b/src/font/charset.c @@ -950,7 +950,7 @@ static const unsigned char* iso8859_8_get_next_word (const unsigned char* mstr, //return sb_get_next_word(mstr, mstrlen, word_info); } -static BidiCharType __mg_iso8859_8_type[] = { +static Uint32 __mg_iso8859_8_type[] = { /*0x00~0x0f*/ BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, BIDI_TYPE_BN, diff --git a/src/font/unicode-bidi-tables.h b/src/font/unicode-bidi-tables.h index d0da7a3d..89781be4 100644 --- a/src/font/unicode-bidi-tables.h +++ b/src/font/unicode-bidi-tables.h @@ -42,9 +42,9 @@ typedef struct _bidichar_type_map { - BidiCharType type; // Type of Unicode characters - Glyph32 glyph; // Starting index of Unicode character - Uint8 count; // Total number of Unicode characters of same type starting from glyphn + Uint32 type; // Type of Unicode characters + Glyph32 glyph; // Starting index of Unicode character + Uint8 count; // Total number of Unicode characters of same type starting from glyphn } BIDICHAR_TYPE_MAP; static const BIDICHAR_TYPE_MAP __mg_unicode_bidi_char_type_map []= diff --git a/src/include/bidi.h b/src/include/bidi.h index 03faee4f..86db14ac 100644 --- a/src/include/bidi.h +++ b/src/include/bidi.h @@ -59,199 +59,6 @@ extern "C" { #define DBGLOG4(s, t1, t2, t3) #endif -/* - * Define some bit masks, that character types are based on, each one has - * only one bit on. - */ - -#define BIDI_MASK_RTL 0x00000001L /* Is right to left */ -#define BIDI_MASK_ARABIC 0x00000002L /* Is arabic */ - -/* Each char can be only one of the three following. */ -#define BIDI_MASK_STRONG 0x00000010L /* Is strong */ -#define BIDI_MASK_WEAK 0x00000020L /* Is weak */ -#define BIDI_MASK_NEUTRAL 0x00000040L /* Is neutral */ -#define BIDI_MASK_SENTINEL 0x00000080L /* Is sentinel: SOT, EOT */ - -/* Each char can be only one of the five following. */ -#define BIDI_MASK_LETTER 0x00000100L /* Is letter: L, R, AL */ -#define BIDI_MASK_NUMBER 0x00000200L /* Is number: EN, AN */ -#define BIDI_MASK_NUMSEPTER 0x00000400L /* Is number separator or terminator: ES, ET, CS */ -#define BIDI_MASK_SPACE 0x00000800L /* Is space: BN, BS, SS, WS */ -#define BIDI_MASK_EXPLICIT 0x00001000L /* Is expilict mark: LRE, RLE, LRO, RLO, PDF */ - -/* Can be on only if BIDI_MASK_SPACE is also on. */ -#define BIDI_MASK_SEPARATOR 0x00002000L /* Is test separator: BS, SS */ -/* Can be on only if BIDI_MASK_EXPLICIT is also on. */ -#define BIDI_MASK_OVERRIDE 0x00004000L /* Is explicit override: LRO, RLO */ - -#define BIDI_MASK_ES 0x00010000L -#define BIDI_MASK_ET 0x00020000L -#define BIDI_MASK_CS 0x00040000L - -#define BIDI_MASK_NSM 0x00080000L -#define BIDI_MASK_BN 0x00100000L - -#define BIDI_MASK_BS 0x00200000L -#define BIDI_MASK_SS 0x00400000L -#define BIDI_MASK_WS 0x00800000L - -/* - * Define values for BidiCharType - */ - -/* Strong left to right */ -#define BIDI_TYPE_LTR (BIDI_MASK_STRONG + BIDI_MASK_LETTER) - -/* Right to left characters */ -#define BIDI_TYPE_RTL (BIDI_MASK_STRONG + BIDI_MASK_LETTER \ - + BIDI_MASK_RTL) - -/* Arabic characters */ -#define BIDI_TYPE_AL (BIDI_MASK_STRONG + BIDI_MASK_LETTER \ - + BIDI_MASK_RTL + BIDI_MASK_ARABIC) - -/* Left-To-Right embedding */ -#define BIDI_TYPE_LRE (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT) - -/* Right-To-Left embedding */ -#define BIDI_TYPE_RLE (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ - + BIDI_MASK_RTL) - -/* Left-To-Right override */ -#define BIDI_TYPE_LRO (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ - + BIDI_MASK_OVERRIDE) - -/* Right-To-Left override */ -#define BIDI_TYPE_RLO (BIDI_MASK_STRONG + BIDI_MASK_EXPLICIT \ - + BIDI_MASK_RTL + BIDI_MASK_OVERRIDE) - -/* Pop directional override */ -#define BIDI_TYPE_PDF (BIDI_MASK_WEAK + BIDI_MASK_EXPLICIT) - -/* European digit */ -#define BIDI_TYPE_EN (BIDI_MASK_WEAK + BIDI_MASK_NUMBER) - -/* Arabic digit */ -#define BIDI_TYPE_AN (BIDI_MASK_WEAK + BIDI_MASK_NUMBER \ - + BIDI_MASK_ARABIC) - -/* European number separator */ -#define BIDI_TYPE_ES (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ - + BIDI_MASK_ES) - -/* European number terminator */ -#define BIDI_TYPE_ET (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ - + BIDI_MASK_ET) - -/* Common Separator */ -#define BIDI_TYPE_CS (BIDI_MASK_WEAK + BIDI_MASK_NUMSEPTER \ - + BIDI_MASK_CS) - -/* Non spacing mark */ -#define BIDI_TYPE_NSM (BIDI_MASK_WEAK + BIDI_MASK_NSM) - -/* Boundary neutral */ -#define BIDI_TYPE_BN (BIDI_MASK_WEAK + BIDI_MASK_SPACE \ - + BIDI_MASK_BN) - -/* Block separator */ -#define BIDI_TYPE_BS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ - + BIDI_MASK_SEPARATOR + BIDI_MASK_BS) - -/* Segment separator */ -#define BIDI_TYPE_SS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ - + BIDI_MASK_SEPARATOR + BIDI_MASK_SS) -/* Whitespace */ -#define BIDI_TYPE_WS (BIDI_MASK_NEUTRAL + BIDI_MASK_SPACE \ - + BIDI_MASK_WS) - -/* Other Neutral */ -#define BIDI_TYPE_ON (BIDI_MASK_NEUTRAL) - -/* The following are used to identify the paragraph direction, - types L, R, N are not used internally anymore, and recommended to use - LTR, RTL and ON instead, didn't removed because of compatability. */ - -#define BIDI_TYPE_L (BIDI_TYPE_LTR) -#define BIDI_TYPE_R (BIDI_TYPE_RTL) -#define BIDI_TYPE_N (BIDI_TYPE_ON) -/* Weak left to right */ -#define BIDI_TYPE_WL (BIDI_MASK_WEAK) -/* Weak right to left */ -#define BIDI_TYPE_WR (BIDI_MASK_WEAK + BIDI_MASK_RTL) - -/* The following are only used internally */ - -/* Start of text */ -#define BIDI_TYPE_SOT (BIDI_MASK_SENTINEL) -/* End of text */ -#define BIDI_TYPE_EOT (BIDI_MASK_SENTINEL + BIDI_MASK_RTL) - -/* Is private-use value? */ -#define BIDI_TYPE_PRIVATE(p) ((p) < 0) - -/* Return the direction of the level number, BIDI_TYPE_LTR for even and - BIDI_TYPE_RTL for odds. */ -#define BIDI_LEVEL_TO_DIR(lev) (BIDI_TYPE_LTR | (lev & 1)) - -/* Return the minimum level of the direction, 0 for BIDI_TYPE_LTR and - 1 for BIDI_TYPE_RTL and BIDI_TYPE_AL. */ -#define BIDI_DIR_TO_LEVEL(dir) ((BYTE)(dir & 1)) - -/* Is right to left? */ -#define BIDI_IS_RTL(p) ((p) & BIDI_MASK_RTL) -/* Is arabic? */ -#define BIDI_IS_ARABIC(p) ((p) & BIDI_MASK_ARABIC) - -/* Is strong? */ -#define BIDI_IS_STRONG(p) ((p) & BIDI_MASK_STRONG) -/* Is weak? */ -#define BIDI_IS_WEAK(p) ((p) & BIDI_MASK_WEAK) -/* Is neutral? */ -#define BIDI_IS_NEUTRAL(p) ((p) & BIDI_MASK_NEUTRAL) -/* Is sentinel? */ -#define BIDI_IS_SENTINEL(p) ((p) & BIDI_MASK_SENTINEL) - -/* Is letter: L, R, AL? */ -#define BIDI_IS_LETTER(p) ((p) & BIDI_MASK_LETTER) -/* Is number: EN, AN? */ -#define BIDI_IS_NUMBER(p) ((p) & BIDI_MASK_NUMBER) -/* Is number separator or terminator: ES, ET, CS? */ -#define BIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR(p) \ - ((p) & BIDI_MASK_NUMSEPTER) - -/* Is space: BN, BS, SS, WS? */ -#define BIDI_IS_SPACE(p) ((p) & BIDI_MASK_SPACE) -/* Is explicit mark: LRE, RLE, LRO, RLO, PDF? */ -#define BIDI_IS_EXPLICIT(p) ((p) & BIDI_MASK_EXPLICIT) - -/* Is test separator: BS, SS? */ -#define BIDI_IS_SEPARATOR(p) ((p) & BIDI_MASK_SEPARATOR) - -/* Is explicit override: LRO, RLO? */ -#define BIDI_IS_OVERRIDE(p) ((p) & BIDI_MASK_OVERRIDE) - -/* Some more: */ - -/* Is left to right letter: LTR? */ -#define BIDI_IS_LTR_LETTER(p) \ - ((p) & (BIDI_MASK_LETTER | BIDI_MASK_RTL) == BIDI_MASK_LETTER) - -/* Is right to left letter: RTL, AL? */ -#define BIDI_IS_RTL_LETTER(p) \ - ((p) & (BIDI_MASK_LETTER | BIDI_MASK_RTL) \ - == (BIDI_MASK_LETTER | BIDI_MASK_RTL)) - -/* Is ES or CS: ES, CS? */ -#define BIDI_IS_ES_OR_CS(p) \ - ((p) & (BIDI_MASK_ES | BIDI_MASK_CS)) - -/* Change numbers: EN, AN to RTL. */ -#define BIDI_NUMBER_TO_RTL(p) \ - (BIDI_IS_NUMBER(p) ? BIDI_TYPE_RTL : (p)) - -typedef Uint32 BidiCharType; typedef struct _TYPERUN TYPERUN; typedef struct _BIDICHAR_MIRROR_MAP { @@ -272,7 +79,7 @@ void __mg_charset_bidi_get_embeddlevels (const CHARSETOPS* charset_ops, Glyph32* Glyph32* __mg_charset_bidi_index_reorder (const CHARSETOPS* charset_ops, Glyph32* glyphs, int len, int* index_map); -BidiCharType __mg_charset_bidi_str_base_dir (const CHARSETOPS* charset_ops, Glyph32* glyphs, int len); +Uint32 __mg_charset_bidi_str_base_dir (const CHARSETOPS* charset_ops, Glyph32* glyphs, int len); #ifdef __cplusplus } diff --git a/src/newgdi/bidi.c b/src/newgdi/bidi.c index 0294ebbd..48c282ac 100644 --- a/src/newgdi/bidi.c +++ b/src/newgdi/bidi.c @@ -940,24 +940,30 @@ int GUIAPI BIDIGetTextLogicalGlyphs( { int i = 0; int left_bytes = text_len; + int nr_chars; int prev_len = 0, len_cur_char = 0; const char* prev_mchar = NULL; Glyph32 glyph_value = INV_GLYPH_VALUE; Glyph32* glyph_string = NULL; GLYPHMAPINFO* map = NULL; - if(glyphs && *glyphs == NULL){ - *glyphs = malloc(text_len * sizeof (Glyph32)); - memset(*glyphs, 0, text_len * sizeof(Glyph32)); + /* use the actual characters count for optimized memory usage. */ + nr_chars = GetTextMCharInfo (log_font, text, text_len, NULL); + + if (glyphs && *glyphs == NULL){ + *glyphs = malloc (nr_chars * sizeof (Glyph32)); + memset (*glyphs, 0, nr_chars * sizeof(Glyph32)); } if(glyphs_map && *glyphs_map == NULL){ - *glyphs_map = malloc(text_len * sizeof (GLYPHMAPINFO)); - memset(*glyphs_map, 0, text_len * sizeof(GLYPHMAPINFO)); + *glyphs_map = malloc (nr_chars * sizeof (GLYPHMAPINFO)); + memset (*glyphs_map, 0, nr_chars * sizeof(GLYPHMAPINFO)); } - if(glyphs) glyph_string = *glyphs; - if(glyphs_map) map = *glyphs_map; - if(!map && !glyph_string) return 0; + + if (glyphs) glyph_string = *glyphs; + if (glyphs_map) map = *glyphs_map; + if (!map && !glyph_string) + return 0; while (left_bytes > 0){ len_cur_char = GetFirstMCharLen(log_font, text, left_bytes); @@ -979,6 +985,7 @@ int GUIAPI BIDIGetTextLogicalGlyphs( i ++; } + return i; } diff --git a/src/sysres/font/makefile.ng b/src/sysres/font/makefile.ng old mode 100755 new mode 100644 From 09e83b6a8bdaeca81bc48cff12628a7ebc252b37 Mon Sep 17 00:00:00 2001 From: 10km <10km0811@sohu.com> Date: Thu, 30 Aug 2018 17:10:26 +0800 Subject: [PATCH 3/9] modified logic judgment for checking JPEG format.JFIF and Exif is morst popular file format of JPEG encoded image,but not all,for MJPEG format that used by camera,the flag is 'AVI1' OR not any flag ,starting FFC0 after FFD8. so the old logic is not work for other JPEG format.see my blog for detail : https://blog.csdn.net/10km/article/details/82155967 --- src/mybmp/jpeg.c | 78 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index e62d94df..6ca8a380 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -258,7 +258,6 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) { int i; unsigned char magic[5]; - Uint16 magic_db; /* This struct contains the JPEG decompression parameters * and pointers to working space @@ -273,17 +272,8 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) if (magic[0] != 0xFF || magic[1] != 0xD8) goto err; /* not JPEG image*/ - magic_db = MGUI_ReadLE16 (fp); - MGUI_RWread (fp, magic, 2, 1); - MGUI_RWread (fp, magic, 4, 1); - magic [4] = '\0'; - if (magic_db != 0xDBFF - && strncmp((char*)magic, "JFIF", 4) != 0 - && strncmp((char*)magic, "Exif", 4) != 0) - goto err; /* not JPEG image*/ - - MGUI_RWseek (fp, -10, SEEK_CUR); + MGUI_RWseek (fp, 0, SEEK_SET); /* Step 1: allocate and initialize JPEG decompression object */ cinfo = calloc (1, sizeof(struct jpeg_decompress_struct)); @@ -318,7 +308,10 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) my_jpeg_data_src (cinfo, fp); /* Step 3: read file parameters with jpeg_read_header() */ - jpeg_read_header (cinfo, TRUE); + if(JPEG_HEADER_OK != jpeg_read_header (cinfo, TRUE)) + { + longjmp (jerr->setjmp_buffer, 1); + } /* Step 4: set parameters for decompression */ cinfo->out_color_space = (mybmp->flags & MYBMP_LOAD_GRAYSCALE) ? JCS_GRAYSCALE: JCS_RGB; @@ -456,24 +449,65 @@ int __mg_load_jpg (MG_RWops* fp, void* init_info, MYBITMAP *my_bmp, BOOL __mg_check_jpg (MG_RWops* fp) { unsigned char magic [5]; - Uint16 magic_db; if (!MGUI_RWread (fp, magic, 2, 1)) return FALSE; /* not JPEG image*/ if (magic[0] != 0xFF || magic[1] != 0xD8) return FALSE; /* not JPEG image*/ - magic_db = MGUI_ReadLE16 (fp); - MGUI_RWread (fp, magic, 2, 1); + MGUI_RWseek (fp, 0, SEEK_SET); - MGUI_RWread (fp, magic, 4, 1); - magic [4] = '\0'; - if (magic_db != 0xDBFF - && strncmp((char*)magic, "JFIF", 4) != 0 - && strncmp((char*)magic, "Exif", 4) != 0) - return FALSE; /* not JPEG image*/ + /* This struct contains the JPEG decompression parameters + * and pointers to working space + * (which is allocated as needed by the JPEG library). + */ + struct jpeg_decompress_struct *cinfo; + struct my_error_mgr *jerr; + jpeg_init_info_t* init_info; - return TRUE; + /* Step 1: allocate and initialize JPEG decompression object */ + cinfo = calloc (1, sizeof(struct jpeg_decompress_struct)); + jerr = calloc (1, sizeof(struct my_error_mgr)); + init_info = calloc (1, sizeof(jpeg_init_info_t)); + + if (cinfo == NULL || jerr == NULL || init_info == NULL) + return FALSE; + + /* We set up the normal JPEG error routines first. */ + cinfo->err = jpeg_std_error (&jerr->pub); + jerr->pub.error_exit = my_error_exit; + + + /* return value*/ + BOOL ret = TRUE; + + /* Establish the setjmp return context for my_error_exit to use. */ + if (setjmp (jerr->setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error */ + ret = FALSE; + goto end; + } + + /* Now we can initialize the JPEG decompression object. */ + jpeg_create_decompress (cinfo); + init_info->dec_started = 0; + + /* Step 2: specify data source */ + my_jpeg_data_src (cinfo, fp); + + /* Step 3: read file parameters with jpeg_read_header() */ + if(JPEG_HEADER_OK != jpeg_read_header (cinfo, TRUE)) + { + longjmp (jerr->setjmp_buffer, 1); + } + +end: + jpeg_destroy_decompress (cinfo); + free (init_info); + free (jerr); + free (cinfo); + return ret; } #endif /* _MGIMAGE_JPG */ From 1297ba836d74176192f8426498caee988a2a61a1 Mon Sep 17 00:00:00 2001 From: 10km <10km0811@sohu.com> Date: Fri, 31 Aug 2018 15:00:50 +0800 Subject: [PATCH 4/9] improve logic of __mg_check_jpg for performance . loop for reading JPEG marker from MG_RWops object,if meet other JPEG marker(eg. SOI,APPn,DQT) skip the payload bytes for next marker,until reach SOF0 or SOF2. about JPEG marker, see also https://en.wikipedia.org/wiki/JPEG --- src/mybmp/jpeg.c | 134 ++++++++++++++++++++++++----------------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index 6ca8a380..00e8f289 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -254,10 +254,37 @@ static void my_error_exit (j_common_ptr cinfo) longjmp (myerr->setjmp_buffer, 1); } +/* + * Common JPEG markers + * see also https://en.wikipedia.org/wiki/JPEG + * */ +#define JMK_SOI 0xFFD8 /* Start Of Image */ +#define JMK_SOF0 0xFFC0 /* Start Of Frame (baseline DCT) */ +#define JMK_SOF2 0xFFC2 /* Start Of Frame (progressive DCT) */ +#define JMK_DHT 0xFFC4 /* Define Huffman Table(s) */ +#define JMK_DQT 0xFFDB /* Define Quantization Table(s) */ +#define JMK_DRI 0xFFDD /* Define Restart Interval */ +#define JMK_SOS 0xFFDA /* Start Of Scan */ +#define JMK_RST_mask 0xFFD0 /* mask of Restart */ +#define JMK_APP_mask 0xFFE0 /* mask of Application-specific */ +#define JMK_COM 0xFFFE /* Comment */ +#define JMK_EOI 0xFFD9 /* End Of Image */ +/** + * Reads a 16-bit big endian integer from a MG_RWops object. + * return TRUE if sucess,or FALSE if the read failed. + */ +static BOOL read_be16 (MG_RWops *fp,Uint16 *value) +{ + if(-1 == MGUI_RWread(fp, value, (sizeof *value), 1)) + return FALSE; + *value = (ArchSwapBE16(*value)); + return TRUE; +} + void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) { int i; - unsigned char magic[5]; + Uint16 soi_marker; /* This struct contains the JPEG decompression parameters * and pointers to working space @@ -267,11 +294,8 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) struct my_error_mgr *jerr; jpeg_init_info_t* init_info; - if (!MGUI_RWread (fp, magic, 2, 1)) - goto err; /* not JPEG image*/ - if (magic[0] != 0xFF || magic[1] != 0xD8) - goto err; /* not JPEG image*/ - + if(!read_be16(fp,&soi_marker) || JMK_SOI != soi_marker ) + goto err; /* not JPEG image*/ MGUI_RWseek (fp, 0, SEEK_SET); @@ -446,68 +470,48 @@ int __mg_load_jpg (MG_RWops* fp, void* init_info, MYBITMAP *my_bmp, return ERR_BMP_OK; } + +/** + * loop read JPEG marker from MG_RWops object,until reach SOF0 or SOF2. + * return TRUE if match JPEG image format,or FALSE if the read failed or not JPEG image + */ BOOL __mg_check_jpg (MG_RWops* fp) { - unsigned char magic [5]; - - if (!MGUI_RWread (fp, magic, 2, 1)) - return FALSE; /* not JPEG image*/ - if (magic[0] != 0xFF || magic[1] != 0xD8) - return FALSE; /* not JPEG image*/ - - MGUI_RWseek (fp, 0, SEEK_SET); - - /* This struct contains the JPEG decompression parameters - * and pointers to working space - * (which is allocated as needed by the JPEG library). - */ - struct jpeg_decompress_struct *cinfo; - struct my_error_mgr *jerr; - jpeg_init_info_t* init_info; - - /* Step 1: allocate and initialize JPEG decompression object */ - cinfo = calloc (1, sizeof(struct jpeg_decompress_struct)); - jerr = calloc (1, sizeof(struct my_error_mgr)); - init_info = calloc (1, sizeof(jpeg_init_info_t)); - - if (cinfo == NULL || jerr == NULL || init_info == NULL) - return FALSE; - - /* We set up the normal JPEG error routines first. */ - cinfo->err = jpeg_std_error (&jerr->pub); - jerr->pub.error_exit = my_error_exit; - - - /* return value*/ - BOOL ret = TRUE; - - /* Establish the setjmp return context for my_error_exit to use. */ - if (setjmp (jerr->setjmp_buffer)) - { - /* If we get here, the JPEG code has signaled an error */ - ret = FALSE; - goto end; + for(Uint16 jpeg_marker;read_be16(fp,&jpeg_marker) /* read JPEG marker */;){ + /* payload length of current marker */ + Uint16 payload = 1; /* set 1 for default, mean that current marker followed by payload bytes*/ + switch(jpeg_marker) + { + case JMK_SOI: + payload = 0; /* no payload */ + break; + case JMK_SOF0: + case JMK_SOF2: + return TRUE; /* JPEG image*/ + case JMK_DHT: + case JMK_DQT: + case JMK_DRI: + case JMK_SOS: + case JMK_COM: + break; + case JMK_EOI: + return FALSE; /* not JPEG image*/ + default: + if((0XFFF8 & jpeg_marker) == JMK_RST_mask){ + payload = 0; /* RST0~7(FFD0~FFD7),no payload */ + }else if((0XFFF0 & jpeg_marker) == JMK_APP_mask){ + /* APP0~APP15,do nothing */ + }else + return FALSE; /* not JPEG image*/ + } + if(payload){ + /*read payload length and skip next marker */ + if(!read_be16(fp,&payload)) + return FALSE; /* not JPEG image*/ + MGUI_RWseek (fp, payload- sizeof(payload), SEEK_CUR); + } } - - /* Now we can initialize the JPEG decompression object. */ - jpeg_create_decompress (cinfo); - init_info->dec_started = 0; - - /* Step 2: specify data source */ - my_jpeg_data_src (cinfo, fp); - - /* Step 3: read file parameters with jpeg_read_header() */ - if(JPEG_HEADER_OK != jpeg_read_header (cinfo, TRUE)) - { - longjmp (jerr->setjmp_buffer, 1); - } - -end: - jpeg_destroy_decompress (cinfo); - free (init_info); - free (jerr); - free (cinfo); - return ret; + return FALSE; /* not JPEG image*/ } #endif /* _MGIMAGE_JPG */ From fcbcc86c6f4a84bb3fbfcbfabb4e879625c6870a Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Fri, 31 Aug 2018 16:57:57 +0800 Subject: [PATCH 5/9] tune for the coding style --- src/mybmp/jpeg.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index 00e8f289..039d58bf 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -273,11 +273,11 @@ static void my_error_exit (j_common_ptr cinfo) * Reads a 16-bit big endian integer from a MG_RWops object. * return TRUE if sucess,or FALSE if the read failed. */ -static BOOL read_be16 (MG_RWops *fp,Uint16 *value) +static BOOL read_be16 (MG_RWops *fp, Uint16 *value) { - if(-1 == MGUI_RWread(fp, value, (sizeof *value), 1)) + if(-1 == MGUI_RWread (fp, value, (sizeof *value), 1)) return FALSE; - *value = (ArchSwapBE16(*value)); + *value = (ArchSwapBE16 (*value)); return TRUE; } @@ -294,7 +294,7 @@ void* __mg_init_jpg (MG_RWops *fp, MYBITMAP* mybmp, RGB* pal) struct my_error_mgr *jerr; jpeg_init_info_t* init_info; - if(!read_be16(fp,&soi_marker) || JMK_SOI != soi_marker ) + if (!read_be16(fp,&soi_marker) || JMK_SOI != soi_marker) goto err; /* not JPEG image*/ MGUI_RWseek (fp, 0, SEEK_SET); @@ -477,40 +477,50 @@ int __mg_load_jpg (MG_RWops* fp, void* init_info, MYBITMAP *my_bmp, */ BOOL __mg_check_jpg (MG_RWops* fp) { - for(Uint16 jpeg_marker;read_be16(fp,&jpeg_marker) /* read JPEG marker */;){ + Uint16 jpeg_marker; + for (; read_be16 (fp, &jpeg_marker) /* read JPEG marker */;) { /* payload length of current marker */ Uint16 payload = 1; /* set 1 for default, mean that current marker followed by payload bytes*/ - switch(jpeg_marker) - { + switch (jpeg_marker) { case JMK_SOI: payload = 0; /* no payload */ break; + case JMK_SOF0: case JMK_SOF2: return TRUE; /* JPEG image*/ + case JMK_DHT: case JMK_DQT: case JMK_DRI: case JMK_SOS: case JMK_COM: break; + case JMK_EOI: return FALSE; /* not JPEG image*/ + default: - if((0XFFF8 & jpeg_marker) == JMK_RST_mask){ + if ((0XFFF8 & jpeg_marker) == JMK_RST_mask) { payload = 0; /* RST0~7(FFD0~FFD7),no payload */ - }else if((0XFFF0 & jpeg_marker) == JMK_APP_mask){ + } + else if ((0XFFF0 & jpeg_marker) == JMK_APP_mask) { /* APP0~APP15,do nothing */ - }else + } + else return FALSE; /* not JPEG image*/ + + break; } - if(payload){ + + if (payload) { /*read payload length and skip next marker */ - if(!read_be16(fp,&payload)) + if (!read_be16 (fp, &payload)) return FALSE; /* not JPEG image*/ - MGUI_RWseek (fp, payload- sizeof(payload), SEEK_CUR); + MGUI_RWseek (fp, payload - sizeof(payload), SEEK_CUR); } } + return FALSE; /* not JPEG image*/ } From ce442b5e969f1f8c89369b4c6c946040eddde047 Mon Sep 17 00:00:00 2001 From: 10km <10km0811@sohu.com> Date: Tue, 4 Sep 2018 13:40:59 +0800 Subject: [PATCH 6/9] add __mg_save_jpg function for storing MYBITMAP as JPEG file. enable application to store image as JPEG file. description: Convert all color space(RGBA,BGR,RGB565,index color256,16) to RGB ,and compress JPEG with JCS_RGB color space. Can use preprocessor _MGIMAGE_JPG_SAVE_QUALITY to define JPEG compression quality.default value 90. For RGBA color space image ,can use _MGIMAGE_JPG_RGBA_BGCOLOR define background color,default value 0XFFFFFF (white). For image with index color space(256 or 16) ,the argument 'pal' of __mg_save_jpg must be NULL. LIMIT:type of MG_RWops object must be RWAREA_TYPE_STDIO ( a file).not suport RWAREA_TYPE_MEM. --- src/include/readbmp.h | 1 + src/mybmp/jpeg.c | 264 ++++++++++++++++++++++++++++++++++++++++++ src/mybmp/mybmp.c | 4 +- 3 files changed, 267 insertions(+), 2 deletions(-) diff --git a/src/include/readbmp.h b/src/include/readbmp.h index da2a1144..b9acceed 100644 --- a/src/include/readbmp.h +++ b/src/include/readbmp.h @@ -114,6 +114,7 @@ BOOL __mg_check_gif (MG_RWops* fp); void* __mg_init_jpg (MG_RWops* fp, MYBITMAP *jpg, RGB *pal); int __mg_load_jpg (MG_RWops* fp, void* init_info, MYBITMAP *jpg, CB_ONE_SCANLINE cb, void* context); void __mg_cleanup_jpg (void* init_info); +int __mg_save_jpg (MG_RWops* fp, MYBITMAP* bmp, RGB* pal); BOOL __mg_check_jpg (MG_RWops* fp); #endif diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index 039d58bf..27570aac 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -524,5 +524,269 @@ BOOL __mg_check_jpg (MG_RWops* fp) return FALSE; /* not JPEG image*/ } +// color space conversion function type for one-row pixel of MYBITMAP +typedef BYTE* (*MYBITMAP_get_pixel_row)(unsigned int cinfo,MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer); + +// convert index(16) color pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_pal16(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + + BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; + RGB rgb; + for (int i = 0; i < mybmp->w; i++) { + + rgb = pal[ bits[i] & 0X0F ]; + + linebuffer[ i ] = rgb.r; + linebuffer[ i + 1 ] = rgb.g; + linebuffer[ i + 2 ] = rgb.b; + + } + return linebuffer; + +} +// convert index(256) color pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_pal256(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + + BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; + RGB rgb; + for (int i = 0; i < mybmp->w; i++) { + + rgb = pal [bits[i] ]; + + linebuffer[ i ] = rgb.r; + linebuffer[ i + 1 ] = rgb.g; + linebuffer[ i + 2 ] = rgb.b; + + } + return linebuffer; + +} + +#define RGB_FROM_RGB565(pixel, r, g, b) \ +{ \ + r = (((pixel&0xF800)>>11)<<3); \ + g = (((pixel&0x07E0)>>5)<<2); \ + b = ((pixel&0x001F)<<3); \ +} + +// convert RGB565 pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_RGB565(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + + Uint16* bits = (Uint16*)(mybmp->bits + mybmp->pitch * next_scanline); + + for (int i = 0, j = 0; i < mybmp->w; i++) { + + RGB_FROM_RGB565(bits[i], linebuffer[ j ++ ], linebuffer[ j ++ ], linebuffer[ j ++ ]) + + } + return linebuffer; + +} +// convert RGB pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_RGB(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + return (JSAMPROW)(mybmp->bits + mybmp->pitch * next_scanline); +} + +// convert BGR pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_BGR(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; + + for (int i = 0, end_i = mybmp->w * 3; i < end_i; i += 3) { + linebuffer[ i ] = bits[ i + 2 ]; + linebuffer[ i + 1 ] = bits[ i + 1 ]; + linebuffer[ i + 2 ] = bits[ i ]; + } + return linebuffer; +} + +#ifndef _MGIMAGE_JPG_RGBA_BGCOLOR +/* background color for RGBA color space conversion,for example: 0xFF0000 is red */ +#define _MGIMAGE_JPG_RGBA_BGCOLOR 0xFFFFFF +#endif + +// convert RGBA pixel line to RGB +static BYTE* MYBITMAP_get_pixel_row_RGBA(unsigned int next_scanline, + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) +{ + RGB* bits = (RGB*)(mybmp->bits + mybmp->pitch * next_scanline); + RGB pixel; + RGB bgcolor = { + (_MGIMAGE_JPG_RGBA_BGCOLOR >> 16) & 0xFF,/* red */ + (_MGIMAGE_JPG_RGBA_BGCOLOR >> 8) & 0xFF,/* green */ + _MGIMAGE_JPG_RGBA_BGCOLOR & 0xFF,/* blue */ + 0x00 /* alpha,no used */ + }; + for (int i = 0,j = 0; i < mybmp->w; i++, j += 3) { + pixel = bits[i]; + /* alpha composite, + * C = Cx * ALPHAx + (1 - ALPHAx) * Cbg + * see also : https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator */ + linebuffer[ j ] = (JSAMPLE)((Uint32)pixel.r * pixel.a >> 8); /* red */ + linebuffer[ j + 1 ] = (JSAMPLE)((Uint32)pixel.g * pixel.a >> 8); /* green */ + linebuffer[ j + 2 ] = (JSAMPLE)((Uint32)pixel.b * pixel.a >> 8); /* blue */ + + linebuffer[ j ] += (JSAMPLE)((Uint32)bgcolor.r * (255 - pixel.a) >> 8); /* red + background color*/ + linebuffer[ j + 1 ] += (JSAMPLE)((Uint32)bgcolor.g * (255 - pixel.a) >> 8); /* green + background color */ + linebuffer[ j + 2 ] += (JSAMPLE)((Uint32)bgcolor.b * (255 - pixel.a) >> 8); /* blue + background color */ + } + return linebuffer; +} + +#ifndef _MGIMAGE_JPG_SAVE_QUALITY +#define _MGIMAGE_JPG_SAVE_QUALITY 90 +#endif + +int __fl_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) +{ + j_compress_ptr cinfo; + struct my_error_mgr *jerr; + JSAMPROW linebuffer = NULL; + JSAMPROW row_pointer[1]; + MYBITMAP_get_pixel_row get_row; + int retcode = ERR_BMP_CANT_SAVE; + + /* Step 1: Allocate and initialize JPEG compression object */ + cinfo = calloc (1, sizeof(struct jpeg_compress_struct)); + + if(NULL == cinfo) + { + fprintf(stderr, "__fl_save_jpg allocation error!\n"); + return ERR_BMP_MEM; + } + jpeg_create_compress(cinfo); + + /* Step 2: Allocate and initialize my_error_mgr object by jpeg_memory_mgr,and init */ + jerr = cinfo->mem->alloc_small((j_common_ptr) cinfo, JPOOL_IMAGE,sizeof(struct my_error_mgr)); + + if(NULL == jerr) + { + retcode = ERR_BMP_MEM; + goto do_finally; + } + memset(jerr,0,sizeof(struct my_error_mgr)); + + /* We set up the normal JPEG error routines first. */ + cinfo->err = jpeg_std_error (&jerr->pub); + jerr->pub.error_exit = my_error_exit; + + /* Establish the setjmp return context for my_error_exit to use. */ + if (setjmp (jerr->setjmp_buffer)) { + fprintf(stderr, "__fl_save_jpg error!\n"); + goto do_finally; + } + /* not supported RWAREA_TYPE_MEM type, + * because the MEM type object can not dynamic allocate memory,so it's not safe */ + if(RWAREA_TYPE_STDIO != fp->type ) + { + fprintf(stderr, "unsupported type of MG_RWops,only support RWAREA_TYPE_STDIO so far\n"); + longjmp (jerr->setjmp_buffer, 1); + } + /* Step 3: specify data source */ + jpeg_stdio_dest(cinfo, fp->hidden.stdio.fp); + + /* Step 4: initialize JPEG compression object */ + /* for JPEG compression, supported color space : JCS_GRAYSCALE,JCS_RGB,JCS_YCbCr,JCS_CMYK,JCS_YCCK + * in this case,MYBITMAP is base on RGB , + * we can select JCS_RGB only,so we must convert all color space (eg.RGBA,BGR,RGB565,...) to RGB + * */ + cinfo->in_color_space = JCS_RGB; + cinfo->image_width = mybmp->w; + cinfo->image_height = mybmp->h; + /* all of MYBMP_TYPE(eg.BRG,RGBA,RGB565...) will be converted to RGB,so input_components is constant 3 */ + cinfo->input_components = 3; + /* set jpeg compression parameters to default */ + jpeg_set_defaults(cinfo); + +#if _MGIMAGE_JPG_SAVE_QUALITY > 0 && _MGIMAGE_JPG_SAVE_QUALITY <= 100 + /* if _MGIMAGE_JPG_SAVE_QUALITY is valid value,use it + * otherwise use default value(75) of libjpeg, + * see also: libjpeg/jcparam.c jpeg_set_defaults function. + * */ + jpeg_set_quality(cinfo, _MGIMAGE_JPG_SAVE_QUALITY, TRUE); +#endif + + int mybmp_type = mybmp->flags & MYBMP_TYPE_MASK; + + switch(mybmp->depth) + { + case 4: + get_row = MYBITMAP_get_pixel_row_pal16; + break; + case 8: + get_row = MYBITMAP_get_pixel_row_pal256; + break; + case 16: + get_row = MYBITMAP_get_pixel_row_RGB565; + break; + case 24: + if(MYBMP_TYPE_RGB == mybmp_type) + get_row = MYBITMAP_get_pixel_row_RGB; + else + get_row = MYBITMAP_get_pixel_row_BGR; + break; + case 32: + get_row = MYBITMAP_get_pixel_row_RGBA; + break; + default: + fprintf(stderr, "invalid MYBITMAP.depth = %d\n",mybmp->depth); + longjmp (jerr->setjmp_buffer, 1); + break; + + } + + if(mybmp->depth <= 8 && NULL == pal) + { + fprintf(stderr, "the 'pal' argument must not be NULL for index color space\n"); + longjmp (jerr->setjmp_buffer, 1); + } + + if(24 == mybmp->depth && MYBMP_TYPE_RGB == mybmp_type) + { + /* + * do nothing while RGB type, + * the MYBITMAP_get_pixel_row function will return address in MYBITMAP.bits data directly, + * without using line buffer + * */ + } + else + { + /* Allocate one-row buffer for color space conversion */ + linebuffer = (JSAMPROW)cinfo->mem->alloc_large + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (cinfo->image_width * cinfo->input_components)); + if(NULL == linebuffer) + { + retcode = ERR_BMP_MEM; + fprintf(stderr, "libjpeg allocation error!\n"); + longjmp (jerr->setjmp_buffer, 1); + } + } + /* Step 5: scan and compress line data */ + jpeg_start_compress(cinfo, TRUE); + while (cinfo->next_scanline < cinfo->image_height) { + /* get one line pixel data with RGB format from MYBITMAP object */ + row_pointer[0] = get_row(cinfo->next_scanline, mybmp, pal, linebuffer); + jpeg_write_scanlines(cinfo, row_pointer, 1); + } + + jpeg_finish_compress(cinfo); + retcode = ERR_BMP_OK; +do_finally: + /* clean up the JPEG object, free the objects and return. */ + jpeg_destroy_compress (cinfo); + free (cinfo); + return retcode; +} + #endif /* _MGIMAGE_JPG */ diff --git a/src/mybmp/mybmp.c b/src/mybmp/mybmp.c index f4292ae8..82799214 100644 --- a/src/mybmp/mybmp.c +++ b/src/mybmp/mybmp.c @@ -80,8 +80,8 @@ static BITMAP_TYPE_INFO bitmap_types [MAX_BITMAP_TYPES] = { "gif", __mg_init_gif, __mg_load_gif, __mg_cleanup_gif, NULL, __mg_check_gif }, #endif #ifdef _MGIMAGE_JPG - { "jpg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, NULL, __mg_check_jpg }, - { "jpeg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, NULL, __mg_check_jpg }, + { "jpg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, __mg_save_jpg, __mg_check_jpg }, + { "jpeg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, __mg_save_jpg, __mg_check_jpg }, #endif #ifdef _MGIMAGE_PNG { "png", __mg_init_png, __mg_load_png, __mg_cleanup_png, NULL, __mg_check_png }, From faa7a2636e7a3ec41bec134fca65e78a8514913f Mon Sep 17 00:00:00 2001 From: 10km <10km0811@sohu.com> Date: Tue, 4 Sep 2018 16:06:06 +0800 Subject: [PATCH 7/9] fix bug for MYBITMAP_get_pixel_row_pal16,MYBITMAP_get_pixel_row_pal256 --- src/mybmp/jpeg.c | 333 ++++++++++++++++++++++++----------------------- 1 file changed, 168 insertions(+), 165 deletions(-) diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index 27570aac..4259b5bd 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -529,40 +529,43 @@ typedef BYTE* (*MYBITMAP_get_pixel_row)(unsigned int cinfo,MYBITMAP* mybmp,RGB* // convert index(16) color pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_pal16(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; - RGB rgb; - for (int i = 0; i < mybmp->w; i++) { + RGB rgb0,rgb1; + for (int i = 0, j = 0, end_i = (mybmp->w + 1) >> 1; i < end_i; ++i) { - rgb = pal[ bits[i] & 0X0F ]; - - linebuffer[ i ] = rgb.r; - linebuffer[ i + 1 ] = rgb.g; - linebuffer[ i + 2 ] = rgb.b; + rgb0 = pal[ (bits[ i ] & 0XF0) >> 4 ]; + rgb1 = pal[ bits[ i ] & 0X0F ]; + linebuffer[ j ++ ] = rgb0.r; + linebuffer[ j ++ ] = rgb0.g; + linebuffer[ j ++ ] = rgb0.b; + linebuffer[ j ++ ] = rgb1.r; + linebuffer[ j ++ ] = rgb1.g; + linebuffer[ j ++ ] = rgb1.b; } - return linebuffer; + return linebuffer; } // convert index(256) color pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_pal256(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; RGB rgb; - for (int i = 0; i < mybmp->w; i++) { + for (int i = 0, j = 0; i < mybmp->w; i++) { - rgb = pal [bits[i] ]; + rgb = pal [bits[i] ]; - linebuffer[ i ] = rgb.r; - linebuffer[ i + 1 ] = rgb.g; - linebuffer[ i + 2 ] = rgb.b; + linebuffer[ j++ ] = rgb.r; + linebuffer[ j++ ] = rgb.g; + linebuffer[ j++ ] = rgb.b; } - return linebuffer; + return linebuffer; } @@ -575,38 +578,38 @@ static BYTE* MYBITMAP_get_pixel_row_pal256(unsigned int next_scanline, // convert RGB565 pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_RGB565(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { - Uint16* bits = (Uint16*)(mybmp->bits + mybmp->pitch * next_scanline); + Uint16* bits = (Uint16*)(mybmp->bits + mybmp->pitch * next_scanline); - for (int i = 0, j = 0; i < mybmp->w; i++) { + for (int i = 0, j = 0; i < mybmp->w; i++) { - RGB_FROM_RGB565(bits[i], linebuffer[ j ++ ], linebuffer[ j ++ ], linebuffer[ j ++ ]) + RGB_FROM_RGB565(bits[i], linebuffer[ j ++ ], linebuffer[ j ++ ], linebuffer[ j ++ ]) } - return linebuffer; + return linebuffer; } // convert RGB pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_RGB(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { - return (JSAMPROW)(mybmp->bits + mybmp->pitch * next_scanline); + return (JSAMPROW)(mybmp->bits + mybmp->pitch * next_scanline); } // convert BGR pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_BGR(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; - for (int i = 0, end_i = mybmp->w * 3; i < end_i; i += 3) { - linebuffer[ i ] = bits[ i + 2 ]; - linebuffer[ i + 1 ] = bits[ i + 1 ]; - linebuffer[ i + 2 ] = bits[ i ]; - } - return linebuffer; + for (int i = 0, end_i = mybmp->w * 3; i < end_i; i += 3) { + linebuffer[ i ] = bits[ i + 2 ]; + linebuffer[ i + 1 ] = bits[ i + 1 ]; + linebuffer[ i + 2 ] = bits[ i ]; + } + return linebuffer; } #ifndef _MGIMAGE_JPG_RGBA_BGCOLOR @@ -616,64 +619,64 @@ static BYTE* MYBITMAP_get_pixel_row_BGR(unsigned int next_scanline, // convert RGBA pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_RGBA(unsigned int next_scanline, - MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) + MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { - RGB* bits = (RGB*)(mybmp->bits + mybmp->pitch * next_scanline); - RGB pixel; - RGB bgcolor = { - (_MGIMAGE_JPG_RGBA_BGCOLOR >> 16) & 0xFF,/* red */ - (_MGIMAGE_JPG_RGBA_BGCOLOR >> 8) & 0xFF,/* green */ - _MGIMAGE_JPG_RGBA_BGCOLOR & 0xFF,/* blue */ - 0x00 /* alpha,no used */ - }; - for (int i = 0,j = 0; i < mybmp->w; i++, j += 3) { - pixel = bits[i]; - /* alpha composite, - * C = Cx * ALPHAx + (1 - ALPHAx) * Cbg - * see also : https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator */ - linebuffer[ j ] = (JSAMPLE)((Uint32)pixel.r * pixel.a >> 8); /* red */ - linebuffer[ j + 1 ] = (JSAMPLE)((Uint32)pixel.g * pixel.a >> 8); /* green */ - linebuffer[ j + 2 ] = (JSAMPLE)((Uint32)pixel.b * pixel.a >> 8); /* blue */ + RGB* bits = (RGB*)(mybmp->bits + mybmp->pitch * next_scanline); + RGB pixel; + RGB bgcolor = { + (_MGIMAGE_JPG_RGBA_BGCOLOR >> 16) & 0xFF,/* red */ + (_MGIMAGE_JPG_RGBA_BGCOLOR >> 8) & 0xFF,/* green */ + _MGIMAGE_JPG_RGBA_BGCOLOR & 0xFF,/* blue */ + 0x00 /* alpha,no used */ + }; + for (int i = 0,j = 0; i < mybmp->w; i++, j += 3) { + pixel = bits[i]; + /* alpha composite, + * C = Cx * ALPHAx + (1 - ALPHAx) * Cbg + * see also : https://en.wikipedia.org/wiki/Alpha_compositing#Analytical_derivation_of_the_over_operator */ + linebuffer[ j ] = (JSAMPLE)((Uint32)pixel.r * pixel.a >> 8); /* red */ + linebuffer[ j + 1 ] = (JSAMPLE)((Uint32)pixel.g * pixel.a >> 8); /* green */ + linebuffer[ j + 2 ] = (JSAMPLE)((Uint32)pixel.b * pixel.a >> 8); /* blue */ - linebuffer[ j ] += (JSAMPLE)((Uint32)bgcolor.r * (255 - pixel.a) >> 8); /* red + background color*/ - linebuffer[ j + 1 ] += (JSAMPLE)((Uint32)bgcolor.g * (255 - pixel.a) >> 8); /* green + background color */ - linebuffer[ j + 2 ] += (JSAMPLE)((Uint32)bgcolor.b * (255 - pixel.a) >> 8); /* blue + background color */ - } - return linebuffer; + linebuffer[ j ] += (JSAMPLE)((Uint32)bgcolor.r * (255 - pixel.a) >> 8); /* red + background color*/ + linebuffer[ j + 1 ] += (JSAMPLE)((Uint32)bgcolor.g * (255 - pixel.a) >> 8); /* green + background color */ + linebuffer[ j + 2 ] += (JSAMPLE)((Uint32)bgcolor.b * (255 - pixel.a) >> 8); /* blue + background color */ + } + return linebuffer; } #ifndef _MGIMAGE_JPG_SAVE_QUALITY #define _MGIMAGE_JPG_SAVE_QUALITY 90 #endif -int __fl_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) +int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) { - j_compress_ptr cinfo; - struct my_error_mgr *jerr; - JSAMPROW linebuffer = NULL; - JSAMPROW row_pointer[1]; - MYBITMAP_get_pixel_row get_row; - int retcode = ERR_BMP_CANT_SAVE; + j_compress_ptr cinfo; + struct my_error_mgr *jerr; + JSAMPROW linebuffer = NULL; + JSAMPROW row_pointer[1]; + MYBITMAP_get_pixel_row get_row; + int retcode = ERR_BMP_CANT_SAVE; - /* Step 1: Allocate and initialize JPEG compression object */ - cinfo = calloc (1, sizeof(struct jpeg_compress_struct)); + /* Step 1: Allocate and initialize JPEG compression object */ + cinfo = calloc (1, sizeof(struct jpeg_compress_struct)); - if(NULL == cinfo) - { - fprintf(stderr, "__fl_save_jpg allocation error!\n"); - return ERR_BMP_MEM; - } - jpeg_create_compress(cinfo); + if(NULL == cinfo) + { + fprintf(stderr, "__fl_save_jpg allocation error!\n"); + return ERR_BMP_MEM; + } + jpeg_create_compress(cinfo); - /* Step 2: Allocate and initialize my_error_mgr object by jpeg_memory_mgr,and init */ - jerr = cinfo->mem->alloc_small((j_common_ptr) cinfo, JPOOL_IMAGE,sizeof(struct my_error_mgr)); + /* Step 2: Allocate and initialize my_error_mgr object by jpeg_memory_mgr,and init */ + jerr = cinfo->mem->alloc_small((j_common_ptr) cinfo, JPOOL_IMAGE,sizeof(struct my_error_mgr)); - if(NULL == jerr) - { - retcode = ERR_BMP_MEM; - goto do_finally; - } - memset(jerr,0,sizeof(struct my_error_mgr)); + if(NULL == jerr) + { + retcode = ERR_BMP_MEM; + goto do_finally; + } + memset(jerr,0,sizeof(struct my_error_mgr)); /* We set up the normal JPEG error routines first. */ cinfo->err = jpeg_std_error (&jerr->pub); @@ -681,111 +684,111 @@ int __fl_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp (jerr->setjmp_buffer)) { - fprintf(stderr, "__fl_save_jpg error!\n"); + fprintf(stderr, "__fl_save_jpg error!\n"); goto do_finally; } /* not supported RWAREA_TYPE_MEM type, * because the MEM type object can not dynamic allocate memory,so it's not safe */ - if(RWAREA_TYPE_STDIO != fp->type ) - { - fprintf(stderr, "unsupported type of MG_RWops,only support RWAREA_TYPE_STDIO so far\n"); - longjmp (jerr->setjmp_buffer, 1); - } - /* Step 3: specify data source */ - jpeg_stdio_dest(cinfo, fp->hidden.stdio.fp); + if(RWAREA_TYPE_STDIO != fp->type ) + { + fprintf(stderr, "unsupported type of MG_RWops,only support RWAREA_TYPE_STDIO so far\n"); + longjmp (jerr->setjmp_buffer, 1); + } + /* Step 3: specify data source */ + jpeg_stdio_dest(cinfo, fp->hidden.stdio.fp); - /* Step 4: initialize JPEG compression object */ - /* for JPEG compression, supported color space : JCS_GRAYSCALE,JCS_RGB,JCS_YCbCr,JCS_CMYK,JCS_YCCK - * in this case,MYBITMAP is base on RGB , - * we can select JCS_RGB only,so we must convert all color space (eg.RGBA,BGR,RGB565,...) to RGB - * */ - cinfo->in_color_space = JCS_RGB; - cinfo->image_width = mybmp->w; - cinfo->image_height = mybmp->h; - /* all of MYBMP_TYPE(eg.BRG,RGBA,RGB565...) will be converted to RGB,so input_components is constant 3 */ - cinfo->input_components = 3; - /* set jpeg compression parameters to default */ - jpeg_set_defaults(cinfo); + /* Step 4: initialize JPEG compression object */ + /* for JPEG compression, supported color space : JCS_GRAYSCALE,JCS_RGB,JCS_YCbCr,JCS_CMYK,JCS_YCCK + * in this case,MYBITMAP is base on RGB , + * we can select JCS_RGB only,so we must convert all color space (eg.RGBA,BGR,RGB565,...) to RGB + * */ + cinfo->in_color_space = JCS_RGB; + cinfo->image_width = mybmp->w; + cinfo->image_height = mybmp->h; + /* all of MYBMP_TYPE(eg.BRG,RGBA,RGB565...) will be converted to RGB,so input_components is constant 3 */ + cinfo->input_components = 3; + /* set jpeg compression parameters to default */ + jpeg_set_defaults(cinfo); #if _MGIMAGE_JPG_SAVE_QUALITY > 0 && _MGIMAGE_JPG_SAVE_QUALITY <= 100 - /* if _MGIMAGE_JPG_SAVE_QUALITY is valid value,use it - * otherwise use default value(75) of libjpeg, - * see also: libjpeg/jcparam.c jpeg_set_defaults function. - * */ - jpeg_set_quality(cinfo, _MGIMAGE_JPG_SAVE_QUALITY, TRUE); + /* if _MGIMAGE_JPG_SAVE_QUALITY is valid value,use it + * otherwise use default value(75) of libjpeg, + * see also: libjpeg/jcparam.c jpeg_set_defaults function. + * */ + jpeg_set_quality(cinfo, _MGIMAGE_JPG_SAVE_QUALITY, TRUE); #endif - int mybmp_type = mybmp->flags & MYBMP_TYPE_MASK; + int mybmp_type = mybmp->flags & MYBMP_TYPE_MASK; - switch(mybmp->depth) - { - case 4: - get_row = MYBITMAP_get_pixel_row_pal16; - break; - case 8: - get_row = MYBITMAP_get_pixel_row_pal256; - break; - case 16: - get_row = MYBITMAP_get_pixel_row_RGB565; - break; - case 24: - if(MYBMP_TYPE_RGB == mybmp_type) - get_row = MYBITMAP_get_pixel_row_RGB; - else - get_row = MYBITMAP_get_pixel_row_BGR; - break; - case 32: - get_row = MYBITMAP_get_pixel_row_RGBA; - break; - default: - fprintf(stderr, "invalid MYBITMAP.depth = %d\n",mybmp->depth); - longjmp (jerr->setjmp_buffer, 1); - break; + switch(mybmp->depth) + { + case 4: + get_row = MYBITMAP_get_pixel_row_pal16; + break; + case 8: + get_row = MYBITMAP_get_pixel_row_pal256; + break; + case 16: + get_row = MYBITMAP_get_pixel_row_RGB565; + break; + case 24: + if(MYBMP_TYPE_RGB == mybmp_type) + get_row = MYBITMAP_get_pixel_row_RGB; + else + get_row = MYBITMAP_get_pixel_row_BGR; + break; + case 32: + get_row = MYBITMAP_get_pixel_row_RGBA; + break; + default: + fprintf(stderr, "invalid MYBITMAP.depth = %d\n",mybmp->depth); + longjmp (jerr->setjmp_buffer, 1); + break; - } + } - if(mybmp->depth <= 8 && NULL == pal) - { - fprintf(stderr, "the 'pal' argument must not be NULL for index color space\n"); - longjmp (jerr->setjmp_buffer, 1); - } + if(mybmp->depth <= 8 && NULL == pal) + { + fprintf(stderr, "the 'pal' argument must not be NULL for index color space\n"); + longjmp (jerr->setjmp_buffer, 1); + } - if(24 == mybmp->depth && MYBMP_TYPE_RGB == mybmp_type) - { - /* - * do nothing while RGB type, - * the MYBITMAP_get_pixel_row function will return address in MYBITMAP.bits data directly, - * without using line buffer - * */ - } - else - { - /* Allocate one-row buffer for color space conversion */ - linebuffer = (JSAMPROW)cinfo->mem->alloc_large - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (cinfo->image_width * cinfo->input_components)); - if(NULL == linebuffer) - { - retcode = ERR_BMP_MEM; - fprintf(stderr, "libjpeg allocation error!\n"); - longjmp (jerr->setjmp_buffer, 1); - } - } - /* Step 5: scan and compress line data */ - jpeg_start_compress(cinfo, TRUE); - while (cinfo->next_scanline < cinfo->image_height) { - /* get one line pixel data with RGB format from MYBITMAP object */ - row_pointer[0] = get_row(cinfo->next_scanline, mybmp, pal, linebuffer); - jpeg_write_scanlines(cinfo, row_pointer, 1); - } + if(24 == mybmp->depth && MYBMP_TYPE_RGB == mybmp_type) + { + /* + * do nothing while RGB type, + * the MYBITMAP_get_pixel_row function will return address in MYBITMAP.bits data directly, + * without using line buffer + * */ + } + else + { + /* Allocate one-row buffer for color space conversion(4 byte alignment) */ + linebuffer = (JSAMPROW)cinfo->mem->alloc_large + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (((cinfo->image_width + 3) & ~3) * cinfo->input_components)); + if(NULL == linebuffer) + { + retcode = ERR_BMP_MEM; + fprintf(stderr, "libjpeg allocation error!\n"); + longjmp (jerr->setjmp_buffer, 1); + } + } + /* Step 5: scan and compress line data */ + jpeg_start_compress(cinfo, TRUE); + while (cinfo->next_scanline < cinfo->image_height) { + /* get one line pixel data with RGB format from MYBITMAP object */ + row_pointer[0] = get_row(cinfo->next_scanline, mybmp, pal, linebuffer); + jpeg_write_scanlines(cinfo, row_pointer, 1); + } - jpeg_finish_compress(cinfo); - retcode = ERR_BMP_OK; + jpeg_finish_compress(cinfo); + retcode = ERR_BMP_OK; do_finally: - /* clean up the JPEG object, free the objects and return. */ - jpeg_destroy_compress (cinfo); - free (cinfo); - return retcode; + /* clean up the JPEG object, free the objects and return. */ + jpeg_destroy_compress (cinfo); + free (cinfo); + return retcode; } #endif /* _MGIMAGE_JPG */ From 6e5407f42db3ee53f42ee03c8cd993e7e6b3d01d Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Tue, 4 Sep 2018 16:33:17 +0800 Subject: [PATCH 8/9] cleaup for coding style --- src/mybmp/jpeg.c | 62 +++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/mybmp/jpeg.c b/src/mybmp/jpeg.c index 4259b5bd..4f41b274 100644 --- a/src/mybmp/jpeg.c +++ b/src/mybmp/jpeg.c @@ -36,6 +36,9 @@ ** ** Current maintainer: Wei Yongming ** +** 2018-09-4 +** Merge pull request from 10km (https://github.com/10km): __mg_save_jpg. +** ** Create date: 2000/08/29 */ @@ -531,10 +534,11 @@ typedef BYTE* (*MYBITMAP_get_pixel_row)(unsigned int cinfo,MYBITMAP* mybmp,RGB* static BYTE* MYBITMAP_get_pixel_row_pal16(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { + int i, j, end_i; BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; - RGB rgb0,rgb1; - for (int i = 0, j = 0, end_i = (mybmp->w + 1) >> 1; i < end_i; ++i) { + RGB rgb0, rgb1; + for (i = 0, j = 0, end_i = (mybmp->w + 1) >> 1; i < end_i; ++i) { rgb0 = pal[ (bits[ i ] & 0XF0) >> 4 ]; rgb1 = pal[ bits[ i ] & 0X0F ]; @@ -549,14 +553,16 @@ static BYTE* MYBITMAP_get_pixel_row_pal16(unsigned int next_scanline, return linebuffer; } + // convert index(256) color pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_pal256(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { - + int i, j; BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; RGB rgb; - for (int i = 0, j = 0; i < mybmp->w; i++) { + + for (i = 0, j = 0; i < mybmp->w; i++) { rgb = pal [bits[i] ]; @@ -580,17 +586,16 @@ static BYTE* MYBITMAP_get_pixel_row_pal256(unsigned int next_scanline, static BYTE* MYBITMAP_get_pixel_row_RGB565(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { - + int i, j; Uint16* bits = (Uint16*)(mybmp->bits + mybmp->pitch * next_scanline); - for (int i = 0, j = 0; i < mybmp->w; i++) { - + for (i = 0, j = 0; i < mybmp->w; i++) { RGB_FROM_RGB565(bits[i], linebuffer[ j ++ ], linebuffer[ j ++ ], linebuffer[ j ++ ]) - } return linebuffer; } + // convert RGB pixel line to RGB static BYTE* MYBITMAP_get_pixel_row_RGB(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) @@ -602,9 +607,10 @@ static BYTE* MYBITMAP_get_pixel_row_RGB(unsigned int next_scanline, static BYTE* MYBITMAP_get_pixel_row_BGR(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { + int i, end_i; BYTE* bits = mybmp->bits + mybmp->pitch * next_scanline; - for (int i = 0, end_i = mybmp->w * 3; i < end_i; i += 3) { + for (i = 0, end_i = mybmp->w * 3; i < end_i; i += 3) { linebuffer[ i ] = bits[ i + 2 ]; linebuffer[ i + 1 ] = bits[ i + 1 ]; linebuffer[ i + 2 ] = bits[ i ]; @@ -621,6 +627,7 @@ static BYTE* MYBITMAP_get_pixel_row_BGR(unsigned int next_scanline, static BYTE* MYBITMAP_get_pixel_row_RGBA(unsigned int next_scanline, MYBITMAP* mybmp,RGB* pal,BYTE* linebuffer) { + int i, j; RGB* bits = (RGB*)(mybmp->bits + mybmp->pitch * next_scanline); RGB pixel; RGB bgcolor = { @@ -629,7 +636,8 @@ static BYTE* MYBITMAP_get_pixel_row_RGBA(unsigned int next_scanline, _MGIMAGE_JPG_RGBA_BGCOLOR & 0xFF,/* blue */ 0x00 /* alpha,no used */ }; - for (int i = 0,j = 0; i < mybmp->w; i++, j += 3) { + + for (i = 0, j = 0; i < mybmp->w; i++, j += 3) { pixel = bits[i]; /* alpha composite, * C = Cx * ALPHAx + (1 - ALPHAx) * Cbg @@ -656,27 +664,24 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) JSAMPROW linebuffer = NULL; JSAMPROW row_pointer[1]; MYBITMAP_get_pixel_row get_row; + int mybmp_type; int retcode = ERR_BMP_CANT_SAVE; /* Step 1: Allocate and initialize JPEG compression object */ cinfo = calloc (1, sizeof(struct jpeg_compress_struct)); - - if(NULL == cinfo) - { + if (NULL == cinfo) { fprintf(stderr, "__fl_save_jpg allocation error!\n"); return ERR_BMP_MEM; } jpeg_create_compress(cinfo); /* Step 2: Allocate and initialize my_error_mgr object by jpeg_memory_mgr,and init */ - jerr = cinfo->mem->alloc_small((j_common_ptr) cinfo, JPOOL_IMAGE,sizeof(struct my_error_mgr)); - - if(NULL == jerr) - { + jerr = cinfo->mem->alloc_small ((j_common_ptr) cinfo, JPOOL_IMAGE, sizeof(struct my_error_mgr)); + if (NULL == jerr) { retcode = ERR_BMP_MEM; goto do_finally; } - memset(jerr,0,sizeof(struct my_error_mgr)); + memset (jerr, 0, sizeof(struct my_error_mgr)); /* We set up the normal JPEG error routines first. */ cinfo->err = jpeg_std_error (&jerr->pub); @@ -689,11 +694,11 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) } /* not supported RWAREA_TYPE_MEM type, * because the MEM type object can not dynamic allocate memory,so it's not safe */ - if(RWAREA_TYPE_STDIO != fp->type ) - { + if(RWAREA_TYPE_STDIO != fp->type) { fprintf(stderr, "unsupported type of MG_RWops,only support RWAREA_TYPE_STDIO so far\n"); longjmp (jerr->setjmp_buffer, 1); } + /* Step 3: specify data source */ jpeg_stdio_dest(cinfo, fp->hidden.stdio.fp); @@ -718,10 +723,9 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) jpeg_set_quality(cinfo, _MGIMAGE_JPG_SAVE_QUALITY, TRUE); #endif - int mybmp_type = mybmp->flags & MYBMP_TYPE_MASK; + mybmp_type = mybmp->flags & MYBMP_TYPE_MASK; - switch(mybmp->depth) - { + switch(mybmp->depth) { case 4: get_row = MYBITMAP_get_pixel_row_pal16; break; @@ -744,25 +748,21 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) fprintf(stderr, "invalid MYBITMAP.depth = %d\n",mybmp->depth); longjmp (jerr->setjmp_buffer, 1); break; - } - if(mybmp->depth <= 8 && NULL == pal) - { + if (mybmp->depth <= 8 && NULL == pal) { fprintf(stderr, "the 'pal' argument must not be NULL for index color space\n"); longjmp (jerr->setjmp_buffer, 1); } - if(24 == mybmp->depth && MYBMP_TYPE_RGB == mybmp_type) - { + if (24 == mybmp->depth && MYBMP_TYPE_RGB == mybmp_type) { /* * do nothing while RGB type, * the MYBITMAP_get_pixel_row function will return address in MYBITMAP.bits data directly, * without using line buffer * */ } - else - { + else { /* Allocate one-row buffer for color space conversion(4 byte alignment) */ linebuffer = (JSAMPROW)cinfo->mem->alloc_large ((j_common_ptr) cinfo, JPOOL_IMAGE, @@ -774,6 +774,7 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) longjmp (jerr->setjmp_buffer, 1); } } + /* Step 5: scan and compress line data */ jpeg_start_compress(cinfo, TRUE); while (cinfo->next_scanline < cinfo->image_height) { @@ -784,6 +785,7 @@ int __mg_save_jpg (MG_RWops* fp, MYBITMAP* mybmp, RGB* pal) jpeg_finish_compress(cinfo); retcode = ERR_BMP_OK; + do_finally: /* clean up the JPEG object, free the objects and return. */ jpeg_destroy_compress (cinfo); From 120705742e445cfe56a0d48755a3fe8bca9af332 Mon Sep 17 00:00:00 2001 From: Vincent Wei Date: Thu, 6 Sep 2018 16:13:22 +0800 Subject: [PATCH 9/9] cleanup and remove unused code --- include/gdi.h | 18 ------------------ src/font/bitmapfont.c | 18 ++++++++---------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/include/gdi.h b/include/gdi.h index a0d7392f..fd2c9842 100644 --- a/include/gdi.h +++ b/include/gdi.h @@ -8551,24 +8551,6 @@ MG_EXPORT BOOL GUIAPI AddGlyphsToBMPFont (DEVFONT* dev_font, BITMAP* glyph_bmp, */ MG_EXPORT void GUIAPI DestroyBMPFont (DEVFONT* dev_font); -#ifdef _DEBUG -/* - * Dump avl tree info - */ -void dump_tree (DEVFONT *dev_font); - -/* - * look up a node in bitmap font avl tree. - */ -int avl_look_up (DEVFONT *dev_font, char *start_mchar, int n); - -/* - * destroy bitmap font avl tree. - */ -void destroy_avl_tree (DEVFONT *dev_font); - -#endif /* end of _DEBUG */ - #endif /* end of _MGFONT_BMPF */ /** diff --git a/src/font/bitmapfont.c b/src/font/bitmapfont.c index a2e26862..2a7ca0c9 100644 --- a/src/font/bitmapfont.c +++ b/src/font/bitmapfont.c @@ -66,7 +66,7 @@ static int def_glyph_width = 8; /* default bitmap glyph */ static unsigned char def_glyph [] = {0}; -#define DEFGLYPHWIDTH 8; +#define DEFGLYPHWIDTH 8 /*** tree ops ***/ @@ -595,10 +595,9 @@ void DestroyBMPFont (DEVFONT* dev_font) return; } -#ifdef _DEBUG +#if 0 -static int -print_tree_struct ( GLYPHTREENODE *node) +static int print_tree_struct ( GLYPHTREENODE *node) { if (node == NULL) @@ -621,8 +620,7 @@ print_tree_struct ( GLYPHTREENODE *node) return 0; } - -void dump_tree (DEVFONT *dev_font) +static void dump_tree (DEVFONT *dev_font) { if (dev_font == NULL || dev_font->data == NULL || @@ -636,7 +634,7 @@ void dump_tree (DEVFONT *dev_font) _MG_PRINTF ("\n"); } -int avl_look_up (DEVFONT *dev_font, char *start_mchar, int n) +static int avl_look_up (DEVFONT *dev_font, char *start_mchar, int n) { GLYPHTREENODE *p; int offset; @@ -659,7 +657,7 @@ int avl_look_up (DEVFONT *dev_font, char *start_mchar, int n) return 0; } -void destroy_avl_tree (DEVFONT *dev_font) +static void destroy_avl_tree (DEVFONT *dev_font) { if (dev_font && ((BMPFONTINFO *)dev_font->data)->tree != NULL) { @@ -670,7 +668,7 @@ void destroy_avl_tree (DEVFONT *dev_font) } } -void draw_root_bmp (HDC hdc, DEVFONT *dev_font) +static void draw_root_bmp (HDC hdc, DEVFONT *dev_font) { GLYPHTREENODE *root = ((BMPFONTINFO *)dev_font->data)->tree; @@ -681,7 +679,7 @@ void draw_root_bmp (HDC hdc, DEVFONT *dev_font) FillBoxWithBitmap (hdc, 0, 400, 0, 0, root->data); } -#endif /* End of _DEBUG */ +#endif #endif /* End of _MGFONT_BMPF */