| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750 |
- /*
- u8g2_font.c
- Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/)
- Copyright (c) 2016, olikraus@gmail.com
- All rights reserved.
- Redistribution and use in source and binary forms, with or without modification,
- are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright notice, this list
- of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice, this
- list of conditions and the following disclaimer in the documentation and/or other
- materials provided with the distribution.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
- CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "u8g2.h"
- /* size of the font data structure, there is no struct or class... */
- /* this is the size for the new font format */
- #define U8G2_FONT_DATA_STRUCT_SIZE 23
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- static uint8_t luat_u8g2_is_equal_width; //是否是等宽字体
- static uint8_t luat_u8g2_ascii_indentation;//等宽字体ascii码缩进处理
- void luat_u8g2_set_ascii_indentation(uint8_t value) {luat_u8g2_ascii_indentation = value;}
- u8g2_uint_t luat_u8g2_need_ascii_cut(u8g2_uint_t org_delta)
- {
- if (luat_u8g2_is_equal_width) {
- if ((luat_u8g2_ascii_indentation < org_delta)) return org_delta - luat_u8g2_ascii_indentation;
- return ((org_delta - 1) >> 1) + 1;
- }
- return org_delta;
- }
- #endif
- /*
- font data:
- offset bytes description
- 0 1 glyph_cnt number of glyphs
- 1 1 bbx_mode 0: proportional, 1: common height, 2: monospace, 3: multiple of 8
- 2 1 bits_per_0 glyph rle parameter
- 3 1 bits_per_1 glyph rle parameter
- 4 1 bits_per_char_width glyph rle parameter
- 5 1 bits_per_char_height glyph rle parameter
- 6 1 bits_per_char_x glyph rle parameter
- 7 1 bits_per_char_y glyph rle parameter
- 8 1 bits_per_delta_x glyph rle parameter
- 9 1 max_char_width
- 10 1 max_char_height
- 11 1 x offset
- 12 1 y offset (descent)
-
- 13 1 ascent (capital A)
- 14 1 descent (lower g)
- 15 1 ascent '('
- 16 1 descent ')'
-
- 17 1 start pos 'A' high byte
- 18 1 start pos 'A' low byte
- 19 1 start pos 'a' high byte
- 20 1 start pos 'a' low byte
- 21 1 start pos unicode high byte
- 22 1 start pos unicode low byte
- Font build mode, 0: proportional, 1: common height, 2: monospace, 3: multiple of 8
- Font build mode 0:
- - "t"
- - Ref height mode: U8G2_FONT_HEIGHT_MODE_TEXT, U8G2_FONT_HEIGHT_MODE_XTEXT or U8G2_FONT_HEIGHT_MODE_ALL
- - use in transparent mode only (does not look good in solid mode)
- - most compact format
- - different font heights possible
-
- Font build mode 1:
- - "h"
- - Ref height mode: U8G2_FONT_HEIGHT_MODE_ALL
- - transparent or solid mode
- - The height of the glyphs depend on the largest glyph in the font. This means font height depends on postfix "r", "f" and "n".
- */
- /* use case: What is the width and the height of the minimal box into which string s fints? */
- void u8g2_font_GetStrSize(const void *font, const char *s, u8g2_uint_t *width, u8g2_uint_t *height);
- void u8g2_font_GetStrSizeP(const void *font, const char *s, u8g2_uint_t *width, u8g2_uint_t *height);
- /* use case: lower left edge of a minimal box is known, what is the correct x, y position for the string draw procedure */
- void u8g2_font_AdjustXYToDraw(const void *font, const char *s, u8g2_uint_t *x, u8g2_uint_t *y);
- void u8g2_font_AdjustXYToDrawP(const void *font, const char *s, u8g2_uint_t *x, u8g2_uint_t *y);
- /* use case: Baseline origin known, return minimal box */
- void u8g2_font_GetStrMinBox(u8g2_t *u8g2, const void *font, const char *s, u8g2_uint_t *x, u8g2_uint_t *y, u8g2_uint_t *width, u8g2_uint_t *height);
- /* procedures */
- /*========================================================================*/
- /* low level byte and word access */
- /* removed NOINLINE, because it leads to smaller code, might also be faster */
- //static uint8_t u8g2_font_get_byte(const uint8_t *font, uint8_t offset) U8G2_NOINLINE;
- static uint8_t u8g2_font_get_byte(const uint8_t *font, uint8_t offset)
- {
- font += offset;
- return u8x8_pgm_read( font );
- }
- static uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset) U8G2_NOINLINE;
- static uint16_t u8g2_font_get_word(const uint8_t *font, uint8_t offset)
- {
- uint16_t pos;
- font += offset;
- pos = u8x8_pgm_read( font );
- font++;
- pos <<= 8;
- pos += u8x8_pgm_read( font);
- return pos;
- }
- /*========================================================================*/
- /* new font format */
- void u8g2_read_font_info(u8g2_font_info_t *font_info, const uint8_t *font)
- {
- /* offset 0 */
- font_info->glyph_cnt = u8g2_font_get_byte(font, 0);
- font_info->bbx_mode = u8g2_font_get_byte(font, 1);
- font_info->bits_per_0 = u8g2_font_get_byte(font, 2);
- font_info->bits_per_1 = u8g2_font_get_byte(font, 3);
-
- /* offset 4 */
- font_info->bits_per_char_width = u8g2_font_get_byte(font, 4);
- font_info->bits_per_char_height = u8g2_font_get_byte(font, 5);
- font_info->bits_per_char_x = u8g2_font_get_byte(font, 6);
- font_info->bits_per_char_y = u8g2_font_get_byte(font, 7);
- font_info->bits_per_delta_x = u8g2_font_get_byte(font, 8);
-
- /* offset 9 */
- font_info->max_char_width = u8g2_font_get_byte(font, 9);
- font_info->max_char_height = u8g2_font_get_byte(font, 10);
- font_info->x_offset = u8g2_font_get_byte(font, 11);
- font_info->y_offset = u8g2_font_get_byte(font, 12);
-
- /* offset 13 */
- font_info->ascent_A = u8g2_font_get_byte(font, 13);
- font_info->descent_g = u8g2_font_get_byte(font, 14);
- font_info->ascent_para = u8g2_font_get_byte(font, 15);
- font_info->descent_para = u8g2_font_get_byte(font, 16);
-
- /* offset 17 */
- font_info->start_pos_upper_A = u8g2_font_get_word(font, 17);
- font_info->start_pos_lower_a = u8g2_font_get_word(font, 19);
-
- /* offset 21 */
- #ifdef U8G2_WITH_UNICODE
- font_info->start_pos_unicode = u8g2_font_get_word(font, 21);
- #endif
- }
- /* calculate the overall length of the font, only used to create the picture for the google wiki */
- size_t u8g2_GetFontSize(const uint8_t *font_arg)
- {
- uint16_t e;
- const uint8_t *font = font_arg;
- font += U8G2_FONT_DATA_STRUCT_SIZE;
-
- for(;;)
- {
- if ( u8x8_pgm_read( font + 1 ) == 0 )
- break;
- font += u8x8_pgm_read( font + 1 );
- }
-
- /* continue with unicode section */
- font += 2;
- /* skip unicode lookup table */
- font += u8g2_font_get_word(font, 0);
-
- for(;;)
- {
- e = u8x8_pgm_read( font );
- e <<= 8;
- e |= u8x8_pgm_read( font + 1 );
- if ( e == 0 )
- break;
- font += u8x8_pgm_read( font + 2 );
- }
-
- return (font - font_arg) + 2;
- }
- /*========================================================================*/
- /* u8g2 interface, font access */
- uint8_t u8g2_GetFontBBXWidth(u8g2_t *u8g2)
- {
- return u8g2->font_info.max_char_width; /* new font info structure */
- }
- uint8_t u8g2_GetFontBBXHeight(u8g2_t *u8g2)
- {
- return u8g2->font_info.max_char_height; /* new font info structure */
- }
- int8_t u8g2_GetFontBBXOffX(u8g2_t *u8g2) U8G2_NOINLINE;
- int8_t u8g2_GetFontBBXOffX(u8g2_t *u8g2)
- {
- return u8g2->font_info.x_offset; /* new font info structure */
- }
- int8_t u8g2_GetFontBBXOffY(u8g2_t *u8g2) U8G2_NOINLINE;
- int8_t u8g2_GetFontBBXOffY(u8g2_t *u8g2)
- {
- return u8g2->font_info.y_offset; /* new font info structure */
- }
- uint8_t u8g2_GetFontCapitalAHeight(u8g2_t *u8g2) U8G2_NOINLINE;
- uint8_t u8g2_GetFontCapitalAHeight(u8g2_t *u8g2)
- {
- return u8g2->font_info.ascent_A; /* new font info structure */
- }
- /*========================================================================*/
- /* glyph handling */
- /* optimized */
- uint8_t u8g2_font_decode_get_unsigned_bits(u8g2_font_decode_t *f, uint8_t cnt)
- {
- uint8_t val;
- uint8_t bit_pos = f->decode_bit_pos;
- uint8_t bit_pos_plus_cnt;
-
- //val = *(f->decode_ptr);
- val = u8x8_pgm_read( f->decode_ptr );
-
- val >>= bit_pos;
- bit_pos_plus_cnt = bit_pos;
- bit_pos_plus_cnt += cnt;
- if ( bit_pos_plus_cnt >= 8 )
- {
- uint8_t s = 8;
- s -= bit_pos;
- f->decode_ptr++;
- //val |= *(f->decode_ptr) << (8-bit_pos);
- val |= u8x8_pgm_read( f->decode_ptr ) << (s);
- //bit_pos -= 8;
- bit_pos_plus_cnt -= 8;
- }
- val &= (1U<<cnt)-1;
- //bit_pos += cnt;
-
- f->decode_bit_pos = bit_pos_plus_cnt;
- return val;
- }
- /*
- 2 bit --> cnt = 2
- -2,-1,0. 1
- 3 bit --> cnt = 3
- -2,-1,0. 1
- -4,-3,-2,-1,0,1,2,3
- if ( x < 0 )
- r = bits(x-1)+1;
- else
- r = bits(x)+1;
- */
- /* optimized */
- int8_t u8g2_font_decode_get_signed_bits(u8g2_font_decode_t *f, uint8_t cnt)
- {
- int8_t v, d;
- v = (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt);
- d = 1;
- cnt--;
- d <<= cnt;
- v -= d;
- return v;
- //return (int8_t)u8g2_font_decode_get_unsigned_bits(f, cnt) - ((1<<cnt)>>1);
- }
- #ifdef U8G2_WITH_FONT_ROTATION
- u8g2_uint_t u8g2_add_vector_y(u8g2_uint_t dy, int8_t x, int8_t y, uint8_t dir)
- {
- switch(dir)
- {
- case 0:
- dy += y;
- break;
- case 1:
- dy += x;
- break;
- case 2:
- dy -= y;
- break;
- default:
- dy -= x;
- break;
- }
- return dy;
- }
- u8g2_uint_t u8g2_add_vector_x(u8g2_uint_t dx, int8_t x, int8_t y, uint8_t dir)
- {
- switch(dir)
- {
- case 0:
- dx += x;
- break;
- case 1:
- dx -= y;
- break;
- case 2:
- dx -= x;
- break;
- default:
- dx += y;
- break;
- }
- return dx;
- }
- /*
- // does not make sense, 50 bytes more required on avr
- void u8g2_add_vector(u8g2_uint_t *xp, u8g2_uint_t *yp, int8_t x, int8_t y, uint8_t dir)
- {
- u8g2_uint_t x_ = *xp;
- u8g2_uint_t y_ = *yp;
- switch(dir)
- {
- case 0:
- y_ += y;
- x_ += x;
- break;
- case 1:
- y_ += x;
- x_ -= y;
- break;
- case 2:
- y_ -= y;
- x_ -= x;
- break;
- default:
- y_ -= x;
- x_ += y;
- break;
- }
- *xp = x_;
- *yp = y_;
- }
- */
- #endif
- /*
- Description:
- Draw a run-length area of the glyph. "len" can have any size and the line
- length has to be wrapped at the glyph border.
- Args:
- len: Length of the line
- is_foreground foreground/background?
- u8g2->font_decode.target_x X position
- u8g2->font_decode.target_y Y position
- u8g2->font_decode.is_transparent Transparent mode
- Return:
- -
- Calls:
- u8g2_Draw90Line()
- Called by:
- u8g2_font_decode_glyph()
- */
- /* optimized */
- void u8g2_font_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground)
- {
- uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
- uint8_t rem; /* remaining pixel to the right edge of the glyph */
- uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
- /* current is either equal to cnt or equal to rem */
-
- /* local coordinates of the glyph */
- uint8_t lx,ly;
-
- /* target position on the screen */
- u8g2_uint_t x, y;
-
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
-
- cnt = len;
-
- /* get the local position */
- lx = decode->x;
- ly = decode->y;
-
- for(;;)
- {
- /* calculate the number of pixel to the right edge of the glyph */
- rem = decode->glyph_width;
- rem -= lx;
-
- /* calculate how many pixel to draw. This is either to the right edge */
- /* or lesser, if not enough pixel are left */
- current = rem;
- if ( cnt < rem )
- current = cnt;
-
-
- /* now draw the line, but apply the rotation around the glyph target position */
- //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
- /* get target position */
- x = decode->target_x;
- y = decode->target_y;
- /* apply rotation */
- #ifdef U8G2_WITH_FONT_ROTATION
-
- x = u8g2_add_vector_x(x, lx, ly, decode->dir);
- y = u8g2_add_vector_y(y, lx, ly, decode->dir);
-
- //u8g2_add_vector(&x, &y, lx, ly, decode->dir);
-
- #else
- x += lx;
- y += ly;
- #endif
-
- /* draw foreground and background (if required) */
- if ( is_foreground )
- {
- u8g2->draw_color = decode->fg_color; /* draw_color will be restored later */
- u8g2_DrawHVLine(u8g2,
- x,
- y,
- current,
- #ifdef U8G2_WITH_FONT_ROTATION
- /* dir */ decode->dir
- #else
- 0
- #endif
- );
- }
- else if ( decode->is_transparent == 0 )
- {
- u8g2->draw_color = decode->bg_color; /* draw_color will be restored later */
- u8g2_DrawHVLine(u8g2,
- x,
- y,
- current,
- #ifdef U8G2_WITH_FONT_ROTATION
- /* dir */ decode->dir
- #else
- 0
- #endif
- );
- }
-
- /* check, whether the end of the run length code has been reached */
- if ( cnt < rem )
- break;
- cnt -= rem;
- lx = 0;
- ly++;
- }
- lx += cnt;
-
- decode->x = lx;
- decode->y = ly;
- }
- void u8g2_font_2x_decode_len(u8g2_t *u8g2, uint8_t len, uint8_t is_foreground)
- {
- uint8_t cnt; /* total number of remaining pixels, which have to be drawn */
- uint8_t rem; /* remaining pixel to the right edge of the glyph */
- uint8_t current; /* number of pixels, which need to be drawn for the draw procedure */
- /* current is either equal to cnt or equal to rem */
-
- /* local coordinates of the glyph */
- uint8_t lx,ly;
-
- /* target position on the screen */
- u8g2_uint_t x, y;
-
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
-
- cnt = len;
-
- /* get the local position */
- lx = decode->x;
- ly = decode->y;
-
- for(;;)
- {
- /* calculate the number of pixel to the right edge of the glyph */
- rem = decode->glyph_width;
- rem -= lx;
-
- /* calculate how many pixel to draw. This is either to the right edge */
- /* or lesser, if not enough pixel are left */
- current = rem;
- if ( cnt < rem )
- current = cnt;
-
-
- /* now draw the line, but apply the rotation around the glyph target position */
- //u8g2_font_decode_draw_pixel(u8g2, lx,ly,current, is_foreground);
- /* get target position */
- x = decode->target_x;
- y = decode->target_y;
- x += lx*2;
- y += ly*2;
-
- /* draw foreground and background (if required) */
- if ( is_foreground )
- {
- u8g2->draw_color = decode->fg_color; /* draw_color will be restored later */
- u8g2_DrawHVLine(u8g2,
- x,
- y,
- current*2,
- 0
- );
- u8g2_DrawHVLine(u8g2,
- x,
- y+1,
- current*2,
- 0
- );
- }
- else if ( decode->is_transparent == 0 )
- {
- u8g2->draw_color = decode->bg_color; /* draw_color will be restored later */
- u8g2_DrawHVLine(u8g2,
- x,
- y,
- current*2,
- 0
- );
- u8g2_DrawHVLine(u8g2,
- x,
- y+1,
- current*2,
- 0
- );
- }
-
- /* check, whether the end of the run length code has been reached */
- if ( cnt < rem )
- break;
- cnt -= rem;
- lx = 0;
- ly++;
- }
- lx += cnt;
-
- decode->x = lx;
- decode->y = ly;
-
- }
- static void u8g2_font_setup_decode(u8g2_t *u8g2, const uint8_t *glyph_data)
- {
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
- decode->decode_ptr = glyph_data;
- decode->decode_bit_pos = 0;
-
- /* 8 Nov 2015, this is already done in the glyph data search procedure */
- /*
- decode->decode_ptr += 1;
- decode->decode_ptr += 1;
- */
-
- decode->glyph_width = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_char_width);
- decode->glyph_height = u8g2_font_decode_get_unsigned_bits(decode,u8g2->font_info.bits_per_char_height);
-
- decode->fg_color = u8g2->draw_color;
- decode->bg_color = (decode->fg_color == 0 ? 1 : 0);
- }
- /*
- Description:
- Decode and draw a glyph.
- Args:
- glyph_data: Pointer to the compressed glyph data of the font
- u8g2->font_decode.target_x X position
- u8g2->font_decode.target_y Y position
- u8g2->font_decode.is_transparent Transparent mode
- Return:
- Width (delta x advance) of the glyph.
- Calls:
- u8g2_font_decode_len()
- */
- /* optimized */
- int8_t u8g2_font_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data)
- {
- uint8_t a, b;
- int8_t x, y;
- int8_t d;
- int8_t h;
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
-
- u8g2_font_setup_decode(u8g2, glyph_data); /* set values in u8g2->font_decode data structure */
- h = u8g2->font_decode.glyph_height;
-
- x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
- y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
- d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
-
- if ( decode->glyph_width > 0 )
- {
- #ifdef U8G2_WITH_FONT_ROTATION
- decode->target_x = u8g2_add_vector_x(decode->target_x, x, -(h+y), decode->dir);
- decode->target_y = u8g2_add_vector_y(decode->target_y, x, -(h+y), decode->dir);
-
- //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
- #else
- decode->target_x += x;
- decode->target_y -= h+y;
- #endif
- //u8g2_add_vector(&(decode->target_x), &(decode->target_y), x, -(h+y), decode->dir);
- #ifdef U8G2_WITH_INTERSECTION
- {
- u8g2_uint_t x0, x1, y0, y1;
- x0 = decode->target_x;
- y0 = decode->target_y;
- x1 = x0;
- y1 = y0;
-
- #ifdef U8G2_WITH_FONT_ROTATION
- switch(decode->dir)
- {
- case 0:
- x1 += decode->glyph_width;
- y1 += h;
- break;
- case 1:
- x0 -= h;
- x0++; /* shift down, because of assymetric boundaries for the interseciton test */
- x1++;
- y1 += decode->glyph_width;
- break;
- case 2:
- x0 -= decode->glyph_width;
- x0++; /* shift down, because of assymetric boundaries for the interseciton test */
- x1++;
- y0 -= h;
- y0++; /* shift down, because of assymetric boundaries for the interseciton test */
- y1++;
- break;
- case 3:
- x1 += h;
- y0 -= decode->glyph_width;
- y0++; /* shift down, because of assymetric boundaries for the interseciton test */
- y1++;
- break;
- }
- #else /* U8G2_WITH_FONT_ROTATION */
- x1 += decode->glyph_width;
- y1 += h;
- #endif
-
- if ( u8g2_IsIntersection(u8g2, x0, y0, x1, y1) == 0 )
- return d;
- }
- #endif /* U8G2_WITH_INTERSECTION */
-
- /* reset local x/y position */
- decode->x = 0;
- decode->y = 0;
-
- /* decode glyph */
- for(;;)
- {
- a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
- b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
- do
- {
- u8g2_font_decode_len(u8g2, a, 0);
- u8g2_font_decode_len(u8g2, b, 1);
- } while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
- if ( decode->y >= h )
- break;
- }
-
- /* restore the u8g2 draw color, because this is modified by the decode algo */
- u8g2->draw_color = decode->fg_color;
- }
- return d;
- }
- int8_t u8g2_font_2x_decode_glyph(u8g2_t *u8g2, const uint8_t *glyph_data)
- {
- uint8_t a, b;
- int8_t x, y;
- int8_t d;
- int8_t h;
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
-
- u8g2_font_setup_decode(u8g2, glyph_data); /* set values in u8g2->font_decode data structure */
- h = u8g2->font_decode.glyph_height;
-
- x = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
- y = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
- d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
-
- if ( decode->glyph_width > 0 )
- {
- decode->target_x += x;
- decode->target_y -= 2*h+y;
- #ifdef U8G2_WITH_INTERSECTION
- {
- u8g2_uint_t x0, x1, y0, y1;
- x0 = decode->target_x;
- y0 = decode->target_y;
- x1 = x0;
- y1 = y0;
-
- x1 += 2*decode->glyph_width;
- y1 += 2*h;
-
- if ( u8g2_IsIntersection(u8g2, x0, y0, x1, y1) == 0 )
- return 2*d;
- }
- #endif /* U8G2_WITH_INTERSECTION */
-
- /* reset local x/y position */
- decode->x = 0;
- decode->y = 0;
-
- /* decode glyph */
- for(;;)
- {
- a = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_0);
- b = u8g2_font_decode_get_unsigned_bits(decode, u8g2->font_info.bits_per_1);
- do
- {
- u8g2_font_2x_decode_len(u8g2, a, 0);
- u8g2_font_2x_decode_len(u8g2, b, 1);
- } while( u8g2_font_decode_get_unsigned_bits(decode, 1) != 0 );
- if ( decode->y >= h )
- break;
- }
-
- /* restore the u8g2 draw color, because this is modified by the decode algo */
- u8g2->draw_color = decode->fg_color;
- }
- return d*2;
- }
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- #include "luat_fs.h"
- #include "luat_mem.h"
- #endif
- /*
- Description:
- Find the starting point of the glyph data.
- Args:
- encoding: Encoding (ASCII or Unicode) of the glyph
- Return:
- Address of the glyph data or NULL, if the encoding is not avialable in the font.
- */
- const uint8_t *u8g2_font_get_glyph_data(u8g2_t *u8g2, uint16_t encoding)
- {
- // printf("u8g2_font_get_glyph_data: encoding=%02X\n", encoding);
- const uint8_t *font = u8g2->font;
- uint8_t font_data[4] = {0};
- // luat_fs_fread(font_info, 1, 21, u8g2->font_file);
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- if (u8g2->font_file){
- luat_fs_fseek(u8g2->font_file, U8G2_FONT_DATA_STRUCT_SIZE, SEEK_SET);
- if ( encoding <= 255 ){
- if ( encoding >= 'a' ){
- luat_fs_fseek(u8g2->font_file, u8g2->font_info.start_pos_lower_a, SEEK_CUR);
- } else if ( encoding >= 'A' ){
- luat_fs_fseek(u8g2->font_file, u8g2->font_info.start_pos_upper_A, SEEK_CUR);
- }
- for(;;){
- font_data[1] = 0;
- luat_fs_fread(font_data, 1, 2, u8g2->font_file);
- if (font_data[1] == 0) break;
- if (font_data[0] == encoding ){
- if(u8g2->font){
- u8g2->font = luat_heap_realloc(u8g2->font, font_data[1] - 2);
- }else{
- u8g2->font = luat_heap_malloc(font_data[1] - 2);
- }
- luat_fs_fread(u8g2->font, 1, font_data[1] - 2, u8g2->font_file);
- return u8g2->font;
- }
- luat_fs_fseek(u8g2->font_file, font_data[1] - 2, SEEK_CUR);
- }
- }
- #ifdef U8G2_WITH_UNICODE
- else{
- uint16_t e;
- // const uint8_t *unicode_lookup_table;
- // font += u8g2->font_info.start_pos_unicode;
- luat_fs_fseek(u8g2->font_file, u8g2->font_info.start_pos_unicode, SEEK_CUR);
- uint16_t pos_unicode = 0;
- uint16_t unicode_lookup_pos = 0;
- // unicode_lookup_table = font;
- /* issue 596: search for the glyph start in the unicode lookup table */
- // do{
- // font += u8g2_font_get_word(unicode_lookup_table, 0);
- // e = u8g2_font_get_word(unicode_lookup_table, 2);
- // unicode_lookup_table+=4;
- // } while( e < encoding );
- // do{
- // luat_fs_fread(font_data, 1, 4, u8g2->font_file);
- // // uint16_t pos = font_data[0]<<8 | font_data[1];
- // pos_unicode += font_data[0]<<8 | font_data[1];
- // e = font_data[2]<<8 | font_data[3];
- // unicode_lookup_pos+=4;
- // // printf("0: unicode e=%02X\n", e);
- // } while( e < encoding );
- // luat_fs_fseek(u8g2->font_file, pos_unicode - unicode_lookup_pos, SEEK_CUR);
- // printf("1: pos_unicode %d\n", pos_unicode);
- // printf("1: unicode e=%02X\n", e);
- // return NULL;
- for(;;){
- // e = u8x8_pgm_read( font );
- // e <<= 8;
- // e |= u8x8_pgm_read( font + 1 );
- // if ( e == 0 )
- // break;
- // if ( e == encoding ){
- // return font+3; /* skip encoding and glyph size */
- // }
- // font += u8x8_pgm_read( font + 2 );
- luat_fs_fread(font_data, 1, 3, u8g2->font_file);
- e = font_data[0]<<8 | font_data[1];
- if ( e == 0 )
- break;
- // printf("2: unicode e=%02X\n", e);
- if ( e == encoding ){
- if(u8g2->font){
- u8g2->font = luat_heap_realloc(u8g2->font, font_data[2] - 3);
- }else{
- u8g2->font = luat_heap_malloc(font_data[2] - 3);
- }
- luat_fs_fread(u8g2->font, 1, font_data[2] - 3, u8g2->font_file);
- return u8g2->font;
- }
- luat_fs_fseek(u8g2->font_file, font_data[2]-3, SEEK_CUR);
- }
- }
- #endif
- return NULL;
- }
- #endif
- font += U8G2_FONT_DATA_STRUCT_SIZE;
-
- if ( encoding <= 255 )
- {
- if ( encoding >= 'a' )
- {
- font += u8g2->font_info.start_pos_lower_a;
- }
- else if ( encoding >= 'A' )
- {
- font += u8g2->font_info.start_pos_upper_A;
- }
-
- for(;;)
- {
- if ( u8x8_pgm_read( font + 1 ) == 0 )
- break;
- if ( u8x8_pgm_read( font ) == encoding )
- {
- return font+2; /* skip encoding and glyph size */
- }
- font += u8x8_pgm_read( font + 1 );
- }
- }
- #ifdef U8G2_WITH_UNICODE
- else
- {
- uint16_t e;
- const uint8_t *unicode_lookup_table;
-
- // removed, there is now the new index table
- //#ifdef __unix__
- // if ( u8g2->last_font_data != NULL && encoding >= u8g2->last_unicode )
- // {
- // font = u8g2->last_font_data;
- // }
- // else
- //#endif
- font += u8g2->font_info.start_pos_unicode;
- unicode_lookup_table = font;
- /* issue 596: search for the glyph start in the unicode lookup table */
- uint8_t* pos_unicode = font;
- do
- {
- font += u8g2_font_get_word(unicode_lookup_table, 0);
- e = u8g2_font_get_word(unicode_lookup_table, 2);
- unicode_lookup_table+=4;
- //printf("0: unicode e=%02X\n", e);
- } while( e < encoding );
- // printf("1: pos_unicode %d\n", font - pos_unicode);
- // printf("1: unicode e=%02X\n", e);
- for(;;)
- {
- e = u8x8_pgm_read( font );
- e <<= 8;
- e |= u8x8_pgm_read( font + 1 );
-
- // removed, there is now the new index table
- //#ifdef __unix__
- // if ( encoding < e )
- // break;
- //#endif
- if ( e == 0 )
- break;
- // printf("2: unicode e=%02X\n", e);
- if ( e == encoding )
- {
- // removed, there is now the new index table
- //#ifdef __unix__
- // u8g2->last_font_data = font;
- // u8g2->last_unicode = encoding;
- //#endif
- return font+3; /* skip encoding and glyph size */
- }
- font += u8x8_pgm_read( font + 2 );
- }
- }
- #endif
-
- return NULL;
- }
- static u8g2_uint_t u8g2_font_draw_glyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
- {
- u8g2_uint_t dx = 0;
- u8g2->font_decode.target_x = x;
- u8g2->font_decode.target_y = y;
- //u8g2->font_decode.is_transparent = is_transparent; this is already set
- //u8g2->font_decode.dir = dir;
- const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
- if ( glyph_data != NULL )
- {
- dx = u8g2_font_decode_glyph(u8g2, glyph_data);
- }
- return dx;
- }
- static u8g2_uint_t u8g2_font_2x_draw_glyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
- {
- u8g2_uint_t dx = 0;
- u8g2->font_decode.target_x = x;
- u8g2->font_decode.target_y = y;
- const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, encoding);
- if ( glyph_data != NULL )
- {
- dx = u8g2_font_2x_decode_glyph(u8g2, glyph_data);
- }
- return dx;
- }
- uint8_t u8g2_IsGlyph(u8g2_t *u8g2, uint16_t requested_encoding)
- {
- /* updated to new code */
- if ( u8g2_font_get_glyph_data(u8g2, requested_encoding) != NULL )
- return 1;
- return 0;
- }
- /* side effect: updates u8g2->font_decode and u8g2->glyph_x_offset */
- int8_t u8g2_GetGlyphWidth(u8g2_t *u8g2, uint16_t requested_encoding)
- {
- const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, requested_encoding);
- if ( glyph_data == NULL )
- return 0;
-
- u8g2_font_setup_decode(u8g2, glyph_data);
- u8g2->glyph_x_offset = u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_x);
- u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_y);
-
- /* glyph width is here: u8g2->font_decode.glyph_width */
- return u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_delta_x);
- }
- /*
- set one of:
- U8G2_FONT_MODE_TRANSPARENT
- U8G2_FONT_MODE_SOLID
- U8G2_FONT_MODE_NONE
- This has been changed for the new font procedures
- */
- void u8g2_SetFontMode(u8g2_t *u8g2, uint8_t is_transparent)
- {
- u8g2->font_decode.is_transparent = is_transparent; // new font procedures
- }
- u8g2_uint_t u8g2_DrawGlyph(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
- {
- #ifdef U8G2_WITH_FONT_ROTATION
- switch(u8g2->font_decode.dir)
- {
- case 0:
- y += u8g2->font_calc_vref(u8g2);
- break;
- case 1:
- x -= u8g2->font_calc_vref(u8g2);
- break;
- case 2:
- y -= u8g2->font_calc_vref(u8g2);
- break;
- case 3:
- x += u8g2->font_calc_vref(u8g2);
- break;
- }
- #else
- y += u8g2->font_calc_vref(u8g2);
- #endif
- return u8g2_font_draw_glyph(u8g2, x, y, encoding);
- }
- u8g2_uint_t u8g2_DrawGlyphX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint16_t encoding)
- {
- y += 2*u8g2->font_calc_vref(u8g2);
- return u8g2_font_2x_draw_glyph(u8g2, x, y, encoding);
- }
- static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str) U8G2_NOINLINE;
- static u8g2_uint_t u8g2_draw_string(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- uint16_t e;
- u8g2_uint_t delta, sum;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- sum = 0;
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- delta = u8g2_DrawGlyph(u8g2, x, y, e);
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- if (e < 0x0080) delta = luat_u8g2_need_ascii_cut(delta);
- #endif
- #ifdef U8G2_WITH_FONT_ROTATION
- switch(u8g2->font_decode.dir)
- {
- case 0:
- x += delta;
- break;
- case 1:
- y += delta;
- break;
- case 2:
- x -= delta;
- break;
- case 3:
- y -= delta;
- break;
- }
-
- /*
- // requires 10 bytes more on avr
- x = u8g2_add_vector_x(x, delta, 0, u8g2->font_decode.dir);
- y = u8g2_add_vector_y(y, delta, 0, u8g2->font_decode.dir);
- */
- #else
- x += delta;
- #endif
- sum += delta;
- }
- }
- return sum;
- }
- static u8g2_uint_t u8g2_draw_string_2x(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str) U8G2_NOINLINE;
- static u8g2_uint_t u8g2_draw_string_2x(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- uint16_t e;
- u8g2_uint_t delta, sum;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- sum = 0;
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- delta = u8g2_DrawGlyphX2(u8g2, x, y, e);
- x += delta;
- sum += delta;
- }
- }
- return sum;
- }
- u8g2_uint_t u8g2_DrawStr(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_ascii_next;
- return u8g2_draw_string(u8g2, x, y, str);
- }
- u8g2_uint_t u8g2_DrawStrX2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_ascii_next;
- return u8g2_draw_string_2x(u8g2, x, y, str);
- }
- /*
- source: https://en.wikipedia.org/wiki/UTF-8
- Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
- 7 U+0000 U+007F 1 0xxxxxxx
- 11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
- 16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
- 21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- 26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- 31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- */
- u8g2_uint_t u8g2_DrawUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- return u8g2_draw_string(u8g2, x, y, str);
- }
- u8g2_uint_t u8g2_DrawUTF8X2(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- return u8g2_draw_string_2x(u8g2, x, y, str);
- }
- u8g2_uint_t u8g2_DrawExtendedUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, u8g2_kerning_t *kerning, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- uint16_t e_prev = 0x0ffff;
- uint16_t e;
- u8g2_uint_t delta, sum, k;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- sum = 0;
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- delta = u8g2_GetGlyphWidth(u8g2, e);
-
- if ( to_left )
- {
- k = u8g2_GetKerning(u8g2, kerning, e, e_prev);
- delta -= k;
- x -= delta;
- }
- else
- {
- k = u8g2_GetKerning(u8g2, kerning, e_prev, e);
- delta -= k;
- }
- e_prev = e;
- u8g2_DrawGlyph(u8g2, x, y, e);
- if ( to_left )
- {
- }
- else
- {
- x += delta;
- x -= k;
- }
-
- sum += delta;
- }
- }
- return sum;
- }
- u8g2_uint_t u8g2_DrawExtUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t to_left, const uint16_t *kerning_table, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- uint16_t e_prev = 0x0ffff;
- uint16_t e;
- u8g2_uint_t delta, sum, k;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- sum = 0;
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- delta = u8g2_GetGlyphWidth(u8g2, e);
-
- if ( to_left )
- {
- k = u8g2_GetKerningByTable(u8g2, kerning_table, e, e_prev);
- delta -= k;
- x -= delta;
- }
- else
- {
- k = u8g2_GetKerningByTable(u8g2, kerning_table, e_prev, e);
- delta -= k;
- }
- e_prev = e;
- if ( to_left )
- {
- }
- else
- {
- x += delta;
- }
- u8g2_DrawGlyph(u8g2, x, y, e);
- if ( to_left )
- {
- }
- else
- {
- //x += delta;
- //x -= k;
- }
-
- sum += delta;
- }
- }
- return sum;
- }
- /*===============================================*/
- /* set ascent/descent for reference point calculation */
- void u8g2_UpdateRefHeight(u8g2_t *u8g2)
- {
- if ( u8g2->font == NULL )
- return;
- u8g2->font_ref_ascent = u8g2->font_info.ascent_A;
- u8g2->font_ref_descent = u8g2->font_info.descent_g;
- if ( u8g2->font_height_mode == U8G2_FONT_HEIGHT_MODE_TEXT )
- {
- }
- else if ( u8g2->font_height_mode == U8G2_FONT_HEIGHT_MODE_XTEXT )
- {
- if ( u8g2->font_ref_ascent < u8g2->font_info.ascent_para )
- u8g2->font_ref_ascent = u8g2->font_info.ascent_para;
- if ( u8g2->font_ref_descent > u8g2->font_info.descent_para )
- u8g2->font_ref_descent = u8g2->font_info.descent_para;
- }
- else
- {
- if ( u8g2->font_ref_ascent < u8g2->font_info.max_char_height+u8g2->font_info.y_offset )
- u8g2->font_ref_ascent = u8g2->font_info.max_char_height+u8g2->font_info.y_offset;
- if ( u8g2->font_ref_descent > u8g2->font_info.y_offset )
- u8g2->font_ref_descent = u8g2->font_info.y_offset;
- }
- }
- void u8g2_SetFontRefHeightText(u8g2_t *u8g2)
- {
- u8g2->font_height_mode = U8G2_FONT_HEIGHT_MODE_TEXT;
- u8g2_UpdateRefHeight(u8g2);
- }
- void u8g2_SetFontRefHeightExtendedText(u8g2_t *u8g2)
- {
- u8g2->font_height_mode = U8G2_FONT_HEIGHT_MODE_XTEXT;
- u8g2_UpdateRefHeight(u8g2);
- }
- void u8g2_SetFontRefHeightAll(u8g2_t *u8g2)
- {
- u8g2->font_height_mode = U8G2_FONT_HEIGHT_MODE_ALL;
- u8g2_UpdateRefHeight(u8g2);
- }
- /*===============================================*/
- /* callback procedures to correct the y position */
- u8g2_uint_t u8g2_font_calc_vref_font(U8X8_UNUSED u8g2_t *u8g2)
- {
- return 0;
- }
- void u8g2_SetFontPosBaseline(u8g2_t *u8g2)
- {
- u8g2->font_calc_vref = u8g2_font_calc_vref_font;
- }
- u8g2_uint_t u8g2_font_calc_vref_bottom(u8g2_t *u8g2)
- {
- return (u8g2_uint_t)(u8g2->font_ref_descent);
- }
- void u8g2_SetFontPosBottom(u8g2_t *u8g2)
- {
- u8g2->font_calc_vref = u8g2_font_calc_vref_bottom;
- }
- u8g2_uint_t u8g2_font_calc_vref_top(u8g2_t *u8g2)
- {
- u8g2_uint_t tmp;
- /* reference pos is one pixel above the upper edge of the reference glyph */
- tmp = (u8g2_uint_t)(u8g2->font_ref_ascent);
- tmp++;
- return tmp;
- }
- void u8g2_SetFontPosTop(u8g2_t *u8g2)
- {
- u8g2->font_calc_vref = u8g2_font_calc_vref_top;
- }
- u8g2_uint_t u8g2_font_calc_vref_center(u8g2_t *u8g2)
- {
- int8_t tmp;
- tmp = u8g2->font_ref_ascent;
- tmp -= u8g2->font_ref_descent;
- tmp /= 2;
- tmp += u8g2->font_ref_descent;
- return tmp;
- }
- void u8g2_SetFontPosCenter(u8g2_t *u8g2)
- {
- u8g2->font_calc_vref = u8g2_font_calc_vref_center;
- }
- /*===============================================*/
- void u8g2_SetFont(u8g2_t *u8g2, const uint8_t *font)
- {
- if ( u8g2->font != font || font == NULL)
- {
- //#ifdef __unix__
- // u8g2->last_font_data = NULL;
- // u8g2->last_unicode = 0x0ffff;
- //#endif
- u8g2->font = font;
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- if(font == NULL){
- uint8_t font_info[U8G2_FONT_DATA_STRUCT_SIZE] = {0};
- luat_fs_fseek(u8g2->font_file, 0, SEEK_SET);
- luat_fs_fread(font_info, 1, U8G2_FONT_DATA_STRUCT_SIZE, u8g2->font_file);
- u8g2_read_font_info(&(u8g2->font_info), font_info);
- }else
- #endif
- {
- u8g2_read_font_info(&(u8g2->font_info), font);
- }
- u8g2_UpdateRefHeight(u8g2);
- /* u8g2_SetFontPosBaseline(u8g2); */ /* removed with issue 195 */
- #if (defined __LUATOS__) || defined (__USER_CODE__)
- //探测一下是不是等宽字体
- const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, 'a');
- // int8_t x, y;
- int8_t d;
- u8g2_font_decode_t *decode = &(u8g2->font_decode);
- u8g2_font_setup_decode(u8g2, glyph_data); /* set values in u8g2->font_decode data structure */
- u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_x);
- u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_char_y);
- d = u8g2_font_decode_get_signed_bits(decode, u8g2->font_info.bits_per_delta_x);
- luat_u8g2_is_equal_width = (d == u8g2->font_info.max_char_width);
- #endif
- }
- }
- /*===============================================*/
- static uint8_t u8g2_is_all_valid(u8g2_t *u8g2, const char *str) U8G2_NOINLINE;
- static uint8_t u8g2_is_all_valid(u8g2_t *u8g2, const char *str)
- {
- uint16_t e;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- if ( u8g2_font_get_glyph_data(u8g2, e) == NULL )
- return 0;
- }
- }
- return 1;
- }
- uint8_t u8g2_IsAllValidUTF8(u8g2_t *u8g2, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- return u8g2_is_all_valid(u8g2, str);
- }
- /* string calculation is stilll not 100% perfect as it addes the initial string offset to the overall size */
- static u8g2_uint_t u8g2_string_width(u8g2_t *u8g2, const char *str) U8G2_NOINLINE;
- static u8g2_uint_t u8g2_string_width(u8g2_t *u8g2, const char *str)
- {
- uint16_t e;
- u8g2_uint_t w, dx;
- #ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
- int8_t initial_x_offset = -64;
- #endif
-
- u8g2->font_decode.glyph_width = 0;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
-
- /* reset the total width to zero, this will be expanded during calculation */
- w = 0;
- dx = 0;
- // printf("str=<%s>\n", str);
-
- for(;;)
- {
- e = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( e == 0x0ffff )
- break;
- str++;
- if ( e != 0x0fffe )
- {
- dx = u8g2_GetGlyphWidth(u8g2, e); /* delta x value of the glyph, side effect: updates u8g2->glyph_x_offset */
- #ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
- if ( initial_x_offset == -64 )
- initial_x_offset = u8g2->glyph_x_offset;
- #endif
- //printf("'%c' x=%d dx=%d w=%d io=%d ", e, u8g2->glyph_x_offset, dx, u8g2->font_decode.glyph_width, initial_x_offset);
- w += dx;
- }
- }
- //printf("\n");
-
- /* adjust the last glyph, check for issue #16: do not adjust if width is 0 */
- if ( u8g2->font_decode.glyph_width != 0 )
- {
- //printf("string width adjust dx=%d glyph_width=%d x-offset=%d\n", dx, u8g2->font_decode.glyph_width, u8g2->glyph_x_offset);
- w -= dx;
- w += u8g2->font_decode.glyph_width; /* the real pixel width of the glyph, sideeffect of GetGlyphWidth */
- /* issue #46: we have to add the x offset also */
- w += u8g2->glyph_x_offset; /* this value is set as a side effect of u8g2_GetGlyphWidth() */
- #ifdef U8G2_BALANCED_STR_WIDTH_CALCULATION
- /* https://github.com/olikraus/u8g2/issues/1561 */
- if ( initial_x_offset > 0 )
- w+=initial_x_offset;
- #endif
- }
- // printf("w=%d \n", w);
-
- return w;
- }
- int8_t u8g2_GetXOffsetGlyph(u8g2_t *u8g2, uint16_t encoding)
- {
- u8g2_GetGlyphWidth(u8g2, encoding); /* delta x value of the glyph, side effect: updates u8g2->glyph_x_offset */
- return u8g2->glyph_x_offset;
- }
- int8_t u8g2_GetXOffsetUTF8(u8g2_t *u8g2, const char *utf8)
- {
- uint16_t e;
- u8x8_utf8_init(u8g2_GetU8x8(u8g2));
- for(;;) // extract encoding from UTF8 byte stream
- {
- e = u8x8_utf8_next(u8g2_GetU8x8(u8g2), (uint8_t)*utf8);
- if ( e == 0x0ffff )
- return 0;
- if ( e < 0x0fffe ) // 0x0fffe means: just continue
- break;
- utf8++;
- }
- return u8g2_GetXOffsetGlyph(u8g2, e);
- }
- static void u8g2_GetGlyphHorizontalProperties(u8g2_t *u8g2, uint16_t requested_encoding, uint8_t *w, int8_t *ox, int8_t *dx)
- {
- const uint8_t *glyph_data = u8g2_font_get_glyph_data(u8g2, requested_encoding);
- if ( glyph_data == NULL )
- return;
-
- u8g2_font_setup_decode(u8g2, glyph_data);
- *w = u8g2->font_decode.glyph_width;
- *ox = u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_x);
- u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_char_y);
- *dx = u8g2_font_decode_get_signed_bits(&(u8g2->font_decode), u8g2->font_info.bits_per_delta_x);
- }
- /* u8g compatible GetStrX function */
- int8_t u8g2_GetStrX(u8g2_t *u8g2, const char *s)
- {
- uint8_t w;
- int8_t dx;
- int8_t ox = 0;
- u8g2_GetGlyphHorizontalProperties(u8g2, *s, &w, &ox, &dx);
- return ox;
- }
- /*
- Warning: This function needs to be fixed. I think it was taken over from u8glib, but not fixed as of now
- The main difference for this procedure compared to the normal get width, should be, that the initial
- offset is removed
- Idea: for the user interface it probably would be better to add the xoffset of the first char to the end, so that the overall word looks better.
- Maybe then the procedure should be called differently, maybe balanced width instead of exact width
- u8g2_calculate_exact_string_width is now OBSOLETE, instead the above str width calculation has been updated:
- https://github.com/olikraus/u8g2/issues/1561
- */
- #ifdef OBSOLETE
- static u8g2_uint_t u8g2_calculate_exact_string_width(u8g2_t *u8g2, const char *str)
- {
- const char *s = str;
- uint16_t enc;
- u8g2_uint_t w;
- uint8_t cnt;
- uint8_t gw;
- int8_t ox, dx;
-
- /* reset the total minimal width to zero, this will be expanded during calculation */
- w = 0;
-
-
- /* check for empty string, width is already 0 */
- cnt = 0;
-
- for(;;)
- {
- enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*s);
- if ( enc == 0x0ffff )
- break;
- s++;
- if ( enc != 0x0fffe )
- {
- if ( cnt == 0 )
- {
- /* get glyph properties of the first char */
- u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
- }
- cnt++;
- if ( cnt > 2 )
- break;
- }
- }
-
- if ( cnt == 0 )
- return 0;
-
- if ( cnt == 1 )
- return gw;
- /* strlen(s) == 1: width = width(s[0]) */
- /* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */
- /* strlen(s) == 3: width = - offx(s[0]) + deltax(s[0]) + deltax(s[1]) + offx(s[2]) + width(s[2]) */
-
- /* assume that the string has size 2 or more, than start with negative offset-x */
- /* for string with size 1, this will be nullified after the loop */
- w = -ox;
- for(;;)
- {
- enc = u8g2->u8x8.next_cb(u8g2_GetU8x8(u8g2), (uint8_t)*str);
- if ( enc== 0x0ffff )
- break;
- str++;
- if ( enc != 0x0fffe )
- {
- u8g2_GetGlyphHorizontalProperties(u8g2, enc, &gw, &ox, &dx);
- /* if there are still more characters, add the delta to the next glyph */
- w += dx;
- }
- }
-
- /* finally calculate the width of the last char */
- /* here is another exception, if the last char is a blank, use the dx value instead */
- if ( gw != 0 )
- {
- w -= dx; /* remove the last dx */
- /* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */
- w += gw;
- w += ox;
- }
- else
- {
- //w += dx;
- }
-
-
- return w;
-
- }
- #endif
- u8g2_uint_t u8g2_GetStrWidth(u8g2_t *u8g2, const char *s)
- {
- u8g2->u8x8.next_cb = u8x8_ascii_next;
- return u8g2_string_width(u8g2, s);
- }
- /* OBSOLETE
- u8g2_uint_t u8g2_GetExactStrWidth(u8g2_t *u8g2, const char *s)
- {
- u8g2->u8x8.next_cb = u8x8_ascii_next;
- return u8g2_calculate_exact_string_width(u8g2, s);
- }
- */
- /*
- source: https://en.wikipedia.org/wiki/UTF-8
- Bits from to bytes Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
- 7 U+0000 U+007F 1 0xxxxxxx
- 11 U+0080 U+07FF 2 110xxxxx 10xxxxxx
- 16 U+0800 U+FFFF 3 1110xxxx 10xxxxxx 10xxxxxx
- 21 U+10000 U+1FFFFF 4 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
- 26 U+200000 U+3FFFFFF 5 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- 31 U+4000000 U+7FFFFFFF 6 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
- */
- u8g2_uint_t u8g2_GetUTF8Width(u8g2_t *u8g2, const char *str)
- {
- u8g2->u8x8.next_cb = u8x8_utf8_next;
- return u8g2_string_width(u8g2, str);
- }
- void u8g2_SetFontDirection(u8g2_t *u8g2, uint8_t dir)
- {
- #ifdef U8G2_WITH_FONT_ROTATION
- u8g2->font_decode.dir = dir;
- #endif
- }
- /*=======================================*/
- /*
- Draw a string, which is produced by hbshape2u8g2 (libharfbuzz toolchain)
- The data argument should look like this:
- static const unsigned char teststring[] U8X8_PROGMEM = {
- 0x09, 0x28, 0x00, 0x00, // u8g2_DrawGlyph(&u8g2, 0, 0, 2344);
- 0x09, 0x2e, 0x10, 0x00, // u8g2_DrawGlyph(&u8g2, 16, 0, 2350);
- 0x09, 0x38, 0x10, 0x00, // u8g2_DrawGlyph(&u8g2, 32, 0, 2360);
- 0x09, 0x4d, 0x00, 0x00, // u8g2_DrawGlyph(&u8g2, 32, 0, 2381);
- 0x09, 0x24, 0x10, 0x00, // u8g2_DrawGlyph(&u8g2, 48, 0, 2340);
- 0x09, 0x47, 0x00, 0x00, // u8g2_DrawGlyph(&u8g2, 48, 0, 2375);
- 0x00, 0x00 // end of binary
- };
- The data row contains four bytes, which are:
- <encoding high byte> <encoding low byte> <delta-x> <delta-y>
- The last row is marked with encoding=0
- The algorithm is
- Input: x,y
- with all rows (until encoding is 0)
- x += <delta-x>
- y += <delta-y>
- draw glyph with <encoding> at x, y
- A call to this function will require transparent mode:
- u8g2_SetFontMode(&u8g2, 1);
-
- Limitation:
- Glyph delta must be lower than 128, this bascially means, that the glyph size is limited to
- hight/width of 128 pixel
-
- Further details:
- https://github.com/olikraus/u8g2/issues/2656
- */
- void u8g2_DrawHB(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, const unsigned char *data)
- {
- uint16_t encoding = 0;
- for (;;)
- {
- encoding = u8x8_pgm_read(data);
- data++;
- encoding <<= 8;
- encoding |= u8x8_pgm_read(data);
- data++;
- if (encoding == 0)
- break;
- x += (int8_t)u8x8_pgm_read(data);
- data++;
- y += (int8_t)u8x8_pgm_read(data);
- data++;
- u8g2_DrawGlyph(u8g2, x, y, encoding);
- }
- }
|