Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
u8g_font.c
00001 /* 00002 00003 u8g_font.c 00004 00005 U8G Font High Level Interface 00006 00007 Universal 8bit Graphics Library 00008 00009 Copyright (c) 2011, olikraus@gmail.com 00010 All rights reserved. 00011 00012 Redistribution and use in source and binary forms, with or without modification, 00013 are permitted provided that the following conditions are met: 00014 00015 * Redistributions of source code must retain the above copyright notice, this list 00016 of conditions and the following disclaimer. 00017 00018 * Redistributions in binary form must reproduce the above copyright notice, this 00019 list of conditions and the following disclaimer in the documentation and/or other 00020 materials provided with the distribution. 00021 00022 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 00023 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 00024 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00025 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00026 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 00027 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00028 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 00029 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00032 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00033 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 00034 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00035 00036 00037 */ 00038 00039 #include "u8g.h" 00040 00041 /* font api */ 00042 00043 /* pointer to the start adress of the glyph, points to progmem area */ 00044 typedef void * u8g_glyph_t; 00045 00046 /* size of the font data structure, there is no struct or class... */ 00047 #define U8G_FONT_DATA_STRUCT_SIZE 17 00048 00049 /* 00050 ... instead the fields of the font data structure are accessed directly by offset 00051 font information 00052 offset 00053 0 font format 00054 1 FONTBOUNDINGBOX width unsigned 00055 2 FONTBOUNDINGBOX height unsigned 00056 3 FONTBOUNDINGBOX x-offset signed 00057 4 FONTBOUNDINGBOX y-offset signed 00058 5 capital A height unsigned 00059 6 start 'A' 00060 8 start 'a' 00061 10 encoding start 00062 11 encoding end 00063 12 descent 'g' negative: below baseline 00064 13 font max ascent 00065 14 font min decent negative: below baseline 00066 15 font xascent 00067 16 font xdecent negative: below baseline 00068 00069 */ 00070 00071 /* use case: What is the width and the height of the minimal box into which string s fints? */ 00072 void u8g_font_GetStrSize(const void *font, const char *s, u8g_uint_t *width, u8g_uint_t *height); 00073 void u8g_font_GetStrSizeP(const void *font, const char *s, u8g_uint_t *width, u8g_uint_t *height); 00074 00075 /* use case: lower left edge of a minimal box is known, what is the correct x, y position for the string draw procedure */ 00076 void u8g_font_AdjustXYToDraw(const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y); 00077 void u8g_font_AdjustXYToDrawP(const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y); 00078 00079 /* use case: Baseline origin known, return minimal box */ 00080 void u8g_font_GetStrMinBox(u8g_t *u8g, const void *font, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height); 00081 00082 /* procedures */ 00083 00084 /*========================================================================*/ 00085 /* low level byte and word access */ 00086 00087 /* removed NOINLINE, because it leads to smaller code, might also be faster */ 00088 //static uint8_t u8g_font_get_byte(const u8g_fntpgm_uint8_t *font, uint8_t offset) U8G_NOINLINE; 00089 static uint8_t u8g_font_get_byte(const u8g_fntpgm_uint8_t *font, uint8_t offset) 00090 { 00091 font += offset; 00092 return u8g_pgm_read( (u8g_pgm_uint8_t *)font ); 00093 } 00094 00095 static uint16_t u8g_font_get_word(const u8g_fntpgm_uint8_t *font, uint8_t offset) U8G_NOINLINE; 00096 static uint16_t u8g_font_get_word(const u8g_fntpgm_uint8_t *font, uint8_t offset) 00097 { 00098 uint16_t pos; 00099 font += offset; 00100 pos = u8g_pgm_read( (u8g_pgm_uint8_t *)font ); 00101 font++; 00102 pos <<= 8; 00103 pos += u8g_pgm_read( (u8g_pgm_uint8_t *)font); 00104 return pos; 00105 } 00106 00107 /*========================================================================*/ 00108 /* direct access on the font */ 00109 00110 static uint8_t u8g_font_GetFormat(const u8g_fntpgm_uint8_t *font) U8G_NOINLINE; 00111 static uint8_t u8g_font_GetFormat(const u8g_fntpgm_uint8_t *font) 00112 { 00113 return u8g_font_get_byte(font, 0); 00114 } 00115 00116 static uint8_t u8g_font_GetFontGlyphStructureSize(const u8g_fntpgm_uint8_t *font) U8G_NOINLINE; 00117 static uint8_t u8g_font_GetFontGlyphStructureSize(const u8g_fntpgm_uint8_t *font) 00118 { 00119 switch(u8g_font_GetFormat(font)) 00120 { 00121 case 0: return 6; 00122 case 1: return 3; 00123 case 2: return 6; 00124 } 00125 return 3; 00126 } 00127 00128 static uint8_t u8g_font_GetBBXWidth(const void *font) 00129 { 00130 return u8g_font_get_byte(font, 1); 00131 } 00132 00133 static uint8_t u8g_font_GetBBXHeight(const void *font) 00134 { 00135 return u8g_font_get_byte(font, 2); 00136 } 00137 00138 static int8_t u8g_font_GetBBXOffX(const void *font) 00139 { 00140 return u8g_font_get_byte(font, 3); 00141 } 00142 00143 static int8_t u8g_font_GetBBXOffY(const void *font) 00144 { 00145 return u8g_font_get_byte(font, 4); 00146 } 00147 00148 uint8_t u8g_font_GetCapitalAHeight(const void *font) 00149 { 00150 return u8g_font_get_byte(font, 5); 00151 } 00152 00153 uint16_t u8g_font_GetEncoding65Pos(const void *font) U8G_NOINLINE; 00154 uint16_t u8g_font_GetEncoding65Pos(const void *font) 00155 { 00156 return u8g_font_get_word(font, 6); 00157 } 00158 00159 uint16_t u8g_font_GetEncoding97Pos(const void *font) U8G_NOINLINE; 00160 uint16_t u8g_font_GetEncoding97Pos(const void *font) 00161 { 00162 return u8g_font_get_word(font, 8); 00163 } 00164 00165 uint8_t u8g_font_GetFontStartEncoding(const void *font) 00166 { 00167 return u8g_font_get_byte(font, 10); 00168 } 00169 00170 uint8_t u8g_font_GetFontEndEncoding(const void *font) 00171 { 00172 return u8g_font_get_byte(font, 11); 00173 } 00174 00175 int8_t u8g_font_GetLowerGDescent(const void *font) 00176 { 00177 return u8g_font_get_byte(font, 12); 00178 } 00179 00180 int8_t u8g_font_GetFontAscent(const void *font) 00181 { 00182 return u8g_font_get_byte(font, 13); 00183 } 00184 00185 int8_t u8g_font_GetFontDescent(const void *font) 00186 { 00187 return u8g_font_get_byte(font, 14); 00188 } 00189 00190 int8_t u8g_font_GetFontXAscent(const void *font) 00191 { 00192 return u8g_font_get_byte(font, 15); 00193 } 00194 00195 int8_t u8g_font_GetFontXDescent(const void *font) 00196 { 00197 return u8g_font_get_byte(font, 16); 00198 } 00199 00200 00201 /* return the data start for a font and the glyph pointer */ 00202 static uint8_t *u8g_font_GetGlyphDataStart(const void *font, u8g_glyph_t g) 00203 { 00204 return ((u8g_fntpgm_uint8_t *)g) + u8g_font_GetFontGlyphStructureSize(font); 00205 } 00206 00207 /* calculate the overall length of the font, only used to create the picture for the google wiki */ 00208 size_t u8g_font_GetSize(const void *font) 00209 { 00210 uint8_t *p = (uint8_t *)(font); 00211 uint8_t font_format = u8g_font_GetFormat(font); 00212 uint8_t data_structure_size = u8g_font_GetFontGlyphStructureSize(font); 00213 uint8_t start, end; 00214 uint8_t i; 00215 uint8_t mask = 255; 00216 00217 start = u8g_font_GetFontStartEncoding(font); 00218 end = u8g_font_GetFontEndEncoding(font); 00219 00220 if ( font_format == 1 ) 00221 mask = 15; 00222 00223 p += U8G_FONT_DATA_STRUCT_SIZE; /* skip font general information */ 00224 00225 i = start; 00226 for(;;) 00227 { 00228 if ( u8g_pgm_read((u8g_pgm_uint8_t *)(p)) == 255 ) 00229 { 00230 p += 1; 00231 } 00232 else 00233 { 00234 p += u8g_pgm_read( ((u8g_pgm_uint8_t *)(p)) + 2 ) & mask; 00235 p += data_structure_size; 00236 } 00237 if ( i == end ) 00238 break; 00239 i++; 00240 } 00241 00242 return p - (uint8_t *)font; 00243 } 00244 00245 /*========================================================================*/ 00246 /* u8g interface, font access */ 00247 00248 uint8_t u8g_GetFontBBXWidth(u8g_t *u8g) 00249 { 00250 return u8g_font_GetBBXWidth(u8g->font); 00251 } 00252 00253 uint8_t u8g_GetFontBBXHeight(u8g_t *u8g) 00254 { 00255 return u8g_font_GetBBXHeight(u8g->font); 00256 } 00257 00258 int8_t u8g_GetFontBBXOffX(u8g_t *u8g) U8G_NOINLINE; 00259 int8_t u8g_GetFontBBXOffX(u8g_t *u8g) 00260 { 00261 return u8g_font_GetBBXOffX(u8g->font); 00262 } 00263 00264 int8_t u8g_GetFontBBXOffY(u8g_t *u8g) U8G_NOINLINE; 00265 int8_t u8g_GetFontBBXOffY(u8g_t *u8g) 00266 { 00267 return u8g_font_GetBBXOffY(u8g->font); 00268 } 00269 00270 uint8_t u8g_GetFontCapitalAHeight(u8g_t *u8g) U8G_NOINLINE; 00271 uint8_t u8g_GetFontCapitalAHeight(u8g_t *u8g) 00272 { 00273 return u8g_font_GetCapitalAHeight(u8g->font); 00274 } 00275 00276 /*========================================================================*/ 00277 /* glyph handling */ 00278 00279 static void u8g_CopyGlyphDataToCache(u8g_t *u8g, u8g_glyph_t g) 00280 { 00281 uint8_t tmp; 00282 switch( u8g_font_GetFormat(u8g->font) ) 00283 { 00284 case 0: 00285 case 2: 00286 /* 00287 format 0 00288 glyph information 00289 offset 00290 0 BBX width unsigned 00291 1 BBX height unsigned 00292 2 data size unsigned (BBX width + 7)/8 * BBX height 00293 3 DWIDTH signed 00294 4 BBX xoffset signed 00295 5 BBX yoffset signed 00296 byte 0 == 255 indicates empty glyph 00297 */ 00298 u8g->glyph_width = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 0 ); 00299 u8g->glyph_height = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 1 ); 00300 u8g->glyph_dx = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 3 ); 00301 u8g->glyph_x = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 4 ); 00302 u8g->glyph_y = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 5 ); 00303 break; 00304 case 1: 00305 default: 00306 /* 00307 format 1 00308 0 BBX xoffset signed --> upper 4 Bit 00309 0 BBX yoffset signed --> lower 4 Bit 00310 1 BBX width unsigned --> upper 4 Bit 00311 1 BBX height unsigned --> lower 4 Bit 00312 2 data size unsigned -(BBX width + 7)/8 * BBX height --> lower 4 Bit 00313 2 DWIDTH signed --> upper 4 Bit 00314 byte 0 == 255 indicates empty glyph 00315 */ 00316 00317 tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 0 ); 00318 u8g->glyph_y = tmp & 15; 00319 u8g->glyph_y-=2; 00320 tmp >>= 4; 00321 u8g->glyph_x = tmp; 00322 00323 tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 1 ); 00324 u8g->glyph_height = tmp & 15; 00325 tmp >>= 4; 00326 u8g->glyph_width = tmp; 00327 00328 tmp = u8g_pgm_read( ((u8g_pgm_uint8_t *)g) + 2 ); 00329 tmp >>= 4; 00330 u8g->glyph_dx = tmp; 00331 00332 00333 break; 00334 } 00335 } 00336 00337 //void u8g_FillEmptyGlyphCache(u8g_t *u8g) U8G_NOINLINE; 00338 static void u8g_FillEmptyGlyphCache(u8g_t *u8g) 00339 { 00340 u8g->glyph_dx = 0; 00341 u8g->glyph_width = 0; 00342 u8g->glyph_height = 0; 00343 u8g->glyph_x = 0; 00344 u8g->glyph_y = 0; 00345 } 00346 00347 /* 00348 Find (with some speed optimization) and return a pointer to the glyph data structure 00349 Also uncompress (format 1) and copy the content of the data structure to the u8g structure 00350 */ 00351 u8g_glyph_t u8g_GetGlyph(u8g_t *u8g, uint8_t requested_encoding) 00352 { 00353 uint8_t *p = (uint8_t *)(u8g->font); 00354 uint8_t font_format = u8g_font_GetFormat(u8g->font); 00355 uint8_t data_structure_size = u8g_font_GetFontGlyphStructureSize(u8g->font); 00356 uint8_t start, end; 00357 uint16_t pos; 00358 uint8_t i; 00359 uint8_t mask = 255; 00360 00361 if ( font_format == 1 ) 00362 mask = 15; 00363 00364 start = u8g_font_GetFontStartEncoding(u8g->font); 00365 end = u8g_font_GetFontEndEncoding(u8g->font); 00366 00367 pos = u8g_font_GetEncoding97Pos(u8g->font); 00368 if ( requested_encoding >= 97 && pos > 0 ) 00369 { 00370 p+= pos; 00371 start = 97; 00372 } 00373 else 00374 { 00375 pos = u8g_font_GetEncoding65Pos(u8g->font); 00376 if ( requested_encoding >= 65 && pos > 0 ) 00377 { 00378 p+= pos; 00379 start = 65; 00380 } 00381 else 00382 p += U8G_FONT_DATA_STRUCT_SIZE; /* skip font general information */ 00383 } 00384 00385 if ( requested_encoding > end ) 00386 { 00387 u8g_FillEmptyGlyphCache(u8g); 00388 return NULL; /* not found */ 00389 } 00390 00391 i = start; 00392 if ( i <= end ) 00393 { 00394 for(;;) 00395 { 00396 if ( u8g_pgm_read((u8g_pgm_uint8_t *)(p)) == 255 ) 00397 { 00398 p += 1; 00399 } 00400 else 00401 { 00402 if ( i == requested_encoding ) 00403 { 00404 u8g_CopyGlyphDataToCache(u8g, p); 00405 return p; 00406 } 00407 p += u8g_pgm_read( ((u8g_pgm_uint8_t *)(p)) + 2 ) & mask; 00408 p += data_structure_size; 00409 } 00410 if ( i == end ) 00411 break; 00412 i++; 00413 } 00414 } 00415 00416 u8g_FillEmptyGlyphCache(u8g); 00417 00418 return NULL; 00419 } 00420 00421 uint8_t u8g_IsGlyph(u8g_t *u8g, uint8_t requested_encoding) 00422 { 00423 if ( u8g_GetGlyph(u8g, requested_encoding) != NULL ) 00424 return 1; 00425 return 0; 00426 } 00427 00428 int8_t u8g_GetGlyphDeltaX(u8g_t *u8g, uint8_t requested_encoding) 00429 { 00430 if ( u8g_GetGlyph(u8g, requested_encoding) == NULL ) 00431 return 0; /* should never happen, so return something */ 00432 return u8g->glyph_dx; 00433 } 00434 00435 00436 /*========================================================================*/ 00437 /* glyph drawing procedures */ 00438 00439 #ifdef OBSOLETE 00440 /* 00441 Draw a glyph 00442 x,y: left baseline position of the glyph 00443 */ 00444 int8_t u8g_DrawGlyphDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) 00445 { 00446 u8g_glyph_t g; 00447 uint8_t w, h, i, j; 00448 const u8g_pgm_uint8_t *data; 00449 uint8_t bytes_per_line; 00450 u8g_uint_t ix, iy; 00451 00452 g = u8g_GetGlyph(u8g, encoding); 00453 if ( g == NULL ) 00454 return 0; 00455 w = u8g->glyph_width; 00456 h = u8g->glyph_height; 00457 00458 bytes_per_line = w; 00459 bytes_per_line += 7; 00460 bytes_per_line /= 8; 00461 00462 data = u8g_font_GetGlyphDataStart(u8g->font, g); 00463 00464 switch(dir) 00465 { 00466 case 0: 00467 x += u8g->glyph_x; 00468 y -= u8g->glyph_y; 00469 y--; 00470 //u8g_DrawFrame(u8g, x, y-h+1, w, h); 00471 if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) 00472 return u8g->glyph_dx; 00473 00474 iy = y; 00475 iy -= h; 00476 iy++; 00477 00478 for( j = 0; j < h; j++ ) 00479 { 00480 ix = x; 00481 for( i = 0; i < bytes_per_line; i++ ) 00482 { 00483 u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); 00484 data++; 00485 ix+=8; 00486 } 00487 iy++; 00488 } 00489 break; 00490 case 1: 00491 x += u8g->glyph_y; 00492 x++; 00493 y += u8g->glyph_x; 00494 //printf("enc %d, dir %d, x %d, y %d, w %d, h %d\n", encoding, dir, x, y, w, h); 00495 //u8g_DrawFrame(u8g, x, y, h, w); 00496 if ( u8g_IsBBXIntersection(u8g, x, y, h, w) == 0 ) 00497 return u8g->glyph_dx; 00498 00499 ix = x; 00500 ix += h; 00501 ix--; 00502 for( j = 0; j < h; j++ ) 00503 { 00504 iy = y; 00505 for( i = 0; i < bytes_per_line; i++ ) 00506 { 00507 u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); 00508 data++; 00509 iy+=8; 00510 } 00511 ix--; 00512 } 00513 break; 00514 case 2: 00515 x -= u8g->glyph_x; 00516 y += u8g->glyph_y; 00517 y++; 00518 if ( u8g_IsBBXIntersection(u8g, x-w-1, y, w, h) == 0 ) 00519 return u8g->glyph_dx; 00520 00521 iy = y; 00522 iy += h; 00523 iy--; 00524 for( j = 0; j < h; j++ ) 00525 { 00526 ix = x; 00527 for( i = 0; i < bytes_per_line; i++ ) 00528 { 00529 u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); 00530 data++; 00531 ix-=8; 00532 } 00533 iy--; 00534 } 00535 break; 00536 case 3: 00537 x -= u8g->glyph_y; 00538 x--; 00539 y -= u8g->glyph_x; 00540 00541 if ( u8g_IsBBXIntersection(u8g, x-h-1, y-w-1, h, w) == 0 ) 00542 return u8g->glyph_dx; 00543 00544 ix = x; 00545 ix -= h; 00546 ix++; 00547 00548 for( j = 0; j < h; j++ ) 00549 { 00550 iy = y; 00551 for( i = 0; i < bytes_per_line; i++ ) 00552 { 00553 u8g_Draw8Pixel(u8g, ix, iy, dir, u8g_pgm_read(data)); 00554 data++; 00555 iy-=8; 00556 } 00557 ix++; 00558 } 00559 break; 00560 } 00561 return u8g->glyph_dx; 00562 } 00563 #endif 00564 00565 int8_t u8g_draw_glyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00566 { 00567 const u8g_pgm_uint8_t *data; 00568 uint8_t w, h; 00569 uint8_t i, j; 00570 u8g_uint_t ix, iy; 00571 00572 { 00573 u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); 00574 if ( g == NULL ) 00575 return 0; 00576 data = u8g_font_GetGlyphDataStart(u8g->font, g); 00577 } 00578 00579 w = u8g->glyph_width; 00580 h = u8g->glyph_height; 00581 00582 x += u8g->glyph_x; 00583 y -= u8g->glyph_y; 00584 y--; 00585 00586 if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) 00587 return u8g->glyph_dx; 00588 00589 /* now, w is reused as bytes per line */ 00590 w += 7; 00591 w /= 8; 00592 00593 iy = y; 00594 iy -= h; 00595 iy++; 00596 00597 for( j = 0; j < h; j++ ) 00598 { 00599 ix = x; 00600 for( i = 0; i < w; i++ ) 00601 { 00602 u8g_Draw8Pixel(u8g, ix, iy, 0, u8g_pgm_read(data)); 00603 data++; 00604 ix+=8; 00605 } 00606 iy++; 00607 } 00608 return u8g->glyph_dx; 00609 } 00610 00611 int8_t u8g_DrawGlyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00612 { 00613 y += u8g->font_calc_vref(u8g); 00614 return u8g_draw_glyph(u8g, x, y, encoding); 00615 } 00616 00617 int8_t u8g_draw_glyph90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00618 { 00619 const u8g_pgm_uint8_t *data; 00620 uint8_t w, h; 00621 uint8_t i, j; 00622 u8g_uint_t ix, iy; 00623 00624 { 00625 u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); 00626 if ( g == NULL ) 00627 return 0; 00628 data = u8g_font_GetGlyphDataStart(u8g->font, g); 00629 } 00630 00631 w = u8g->glyph_width; 00632 h = u8g->glyph_height; 00633 00634 x += u8g->glyph_y; 00635 x++; 00636 y += u8g->glyph_x; 00637 00638 if ( u8g_IsBBXIntersection(u8g, x, y, h, w) == 0 ) 00639 return u8g->glyph_dx; 00640 00641 /* now, w is reused as bytes per line */ 00642 w += 7; 00643 w /= 8; 00644 00645 ix = x; 00646 ix += h; 00647 ix--; 00648 for( j = 0; j < h; j++ ) 00649 { 00650 iy = y; 00651 for( i = 0; i < w; i++ ) 00652 { 00653 u8g_Draw8Pixel(u8g, ix, iy, 1, u8g_pgm_read(data)); 00654 data++; 00655 iy+=8; 00656 } 00657 ix--; 00658 } 00659 return u8g->glyph_dx; 00660 } 00661 00662 int8_t u8g_DrawGlyph90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00663 { 00664 x -= u8g->font_calc_vref(u8g); 00665 return u8g_draw_glyph90(u8g, x, y, encoding); 00666 } 00667 00668 00669 int8_t u8g_draw_glyph180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00670 { 00671 const u8g_pgm_uint8_t *data; 00672 uint8_t w, h; 00673 uint8_t i, j; 00674 u8g_uint_t ix, iy; 00675 00676 { 00677 u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); 00678 if ( g == NULL ) 00679 return 0; 00680 data = u8g_font_GetGlyphDataStart(u8g->font, g); 00681 } 00682 00683 w = u8g->glyph_width; 00684 h = u8g->glyph_height; 00685 00686 x -= u8g->glyph_x; 00687 y += u8g->glyph_y; 00688 y++; 00689 00690 if ( u8g_IsBBXIntersection(u8g, x-(w-1), y, w, h) == 0 ) 00691 return u8g->glyph_dx; 00692 00693 /* now, w is reused as bytes per line */ 00694 w += 7; 00695 w /= 8; 00696 00697 iy = y; 00698 iy += h; 00699 iy--; 00700 for( j = 0; j < h; j++ ) 00701 { 00702 ix = x; 00703 for( i = 0; i < w; i++ ) 00704 { 00705 u8g_Draw8Pixel(u8g, ix, iy, 2, u8g_pgm_read(data)); 00706 data++; 00707 ix-=8; 00708 } 00709 iy--; 00710 } 00711 return u8g->glyph_dx; 00712 } 00713 00714 int8_t u8g_DrawGlyph180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00715 { 00716 y -= u8g->font_calc_vref(u8g); 00717 return u8g_draw_glyph180(u8g, x, y, encoding); 00718 } 00719 00720 00721 int8_t u8g_draw_glyph270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00722 { 00723 const u8g_pgm_uint8_t *data; 00724 uint8_t w, h; 00725 uint8_t i, j; 00726 u8g_uint_t ix, iy; 00727 00728 { 00729 u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); 00730 if ( g == NULL ) 00731 return 0; 00732 data = u8g_font_GetGlyphDataStart(u8g->font, g); 00733 } 00734 00735 w = u8g->glyph_width; 00736 h = u8g->glyph_height; 00737 00738 x -= u8g->glyph_y; 00739 x--; 00740 y -= u8g->glyph_x; 00741 00742 if ( u8g_IsBBXIntersection(u8g, x-(h-1), y-(w-1), h, w) == 0 ) 00743 return u8g->glyph_dx; 00744 00745 00746 /* now, w is reused as bytes per line */ 00747 w += 7; 00748 w /= 8; 00749 00750 ix = x; 00751 ix -= h; 00752 ix++; 00753 00754 for( j = 0; j < h; j++ ) 00755 { 00756 iy = y; 00757 for( i = 0; i < w; i++ ) 00758 { 00759 u8g_Draw8Pixel(u8g, ix, iy, 3, u8g_pgm_read(data)); 00760 data++; 00761 iy-=8; 00762 } 00763 ix++; 00764 } 00765 return u8g->glyph_dx; 00766 } 00767 00768 int8_t u8g_DrawGlyph270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 00769 { 00770 x += u8g->font_calc_vref(u8g); 00771 return u8g_draw_glyph270(u8g, x, y, encoding); 00772 } 00773 00774 00775 00776 #ifdef OBSOLETE 00777 /* 00778 Draw a glyph 00779 x,y: lower left corner of the font bounding box 00780 */ 00781 int8_t u8g_DrawGlyphFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) 00782 { 00783 /* TODO: apply "dir" */ 00784 x -= u8g_GetFontBBXOffX(u8g); 00785 y += u8g_GetFontBBXOffY(u8g); 00786 return u8g_DrawGlyphDir(u8g, x, y, dir, encoding); 00787 } 00788 #endif 00789 00790 /*========================================================================*/ 00791 /* string drawing procedures */ 00792 00793 00794 u8g_uint_t u8g_DrawStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) 00795 { 00796 u8g_uint_t t = 0; 00797 int8_t d; 00798 00799 //u8g_uint_t u8g_GetStrWidth(u8g, s); 00800 //u8g_font_GetFontAscent(u8g->font)-u8g_font_GetFontDescent(u8g->font); 00801 00802 y += u8g->font_calc_vref(u8g); 00803 00804 while( *s != '\0' ) 00805 { 00806 d = u8g_draw_glyph(u8g, x, y, *s); 00807 x += d; 00808 t += d; 00809 s++; 00810 } 00811 return t; 00812 } 00813 00814 u8g_uint_t u8g_DrawStr90(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) 00815 { 00816 u8g_uint_t t = 0; 00817 int8_t d; 00818 00819 x -= u8g->font_calc_vref(u8g); 00820 00821 while( *s != '\0' ) 00822 { 00823 d = u8g_draw_glyph90(u8g, x, y, *s); 00824 y += d; 00825 t += d; 00826 s++; 00827 } 00828 return t; 00829 } 00830 00831 u8g_uint_t u8g_DrawStr180(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) 00832 { 00833 u8g_uint_t t = 0; 00834 int8_t d; 00835 00836 y -= u8g->font_calc_vref(u8g); 00837 00838 while( *s != '\0' ) 00839 { 00840 d = u8g_draw_glyph180(u8g, x, y, *s); 00841 x -= d; 00842 t += d; 00843 s++; 00844 } 00845 return t; 00846 } 00847 00848 u8g_uint_t u8g_DrawStr270(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) 00849 { 00850 u8g_uint_t t = 0; 00851 int8_t d; 00852 00853 x += u8g->font_calc_vref(u8g); 00854 00855 while( *s != '\0' ) 00856 { 00857 d = u8g_draw_glyph270(u8g, x, y, *s); 00858 y -= d; 00859 t += d; 00860 s++; 00861 } 00862 return t; 00863 } 00864 00865 u8g_uint_t u8g_DrawStrDir(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s) 00866 { 00867 switch(dir) 00868 { 00869 case 0: 00870 return u8g_DrawStr(u8g, x, y, s); 00871 case 1: 00872 return u8g_DrawStr90(u8g, x, y, s); 00873 case 2: 00874 return u8g_DrawStr180(u8g, x, y, s); 00875 case 3: 00876 return u8g_DrawStr270(u8g, x, y, s); 00877 } 00878 return 0; 00879 } 00880 00881 u8g_uint_t u8g_DrawStrP(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) 00882 { 00883 u8g_uint_t t = 0; 00884 int8_t d; 00885 uint8_t c; 00886 00887 y += u8g->font_calc_vref(u8g); 00888 00889 for(;;) 00890 { 00891 c = u8g_pgm_read(s); 00892 if ( c == '\0' ) 00893 break; 00894 d = u8g_draw_glyph(u8g, x, y, c); 00895 x += d; 00896 t += d; 00897 s++; 00898 } 00899 return t; 00900 } 00901 00902 u8g_uint_t u8g_DrawStr90P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) 00903 { 00904 u8g_uint_t t = 0; 00905 int8_t d; 00906 00907 x -= u8g->font_calc_vref(u8g); 00908 00909 while( *s != '\0' ) 00910 { 00911 d = u8g_DrawGlyph90(u8g, x, y, u8g_pgm_read(s)); 00912 y += d; 00913 t += d; 00914 s++; 00915 } 00916 return t; 00917 } 00918 00919 u8g_uint_t u8g_DrawStr180P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) 00920 { 00921 u8g_uint_t t = 0; 00922 int8_t d; 00923 00924 y -= u8g->font_calc_vref(u8g); 00925 00926 while( *s != '\0' ) 00927 { 00928 d = u8g_DrawGlyph180(u8g, x, y, u8g_pgm_read(s)); 00929 x -= d; 00930 t += d; 00931 s++; 00932 } 00933 return t; 00934 } 00935 00936 u8g_uint_t u8g_DrawStr270P(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const u8g_pgm_uint8_t *s) 00937 { 00938 u8g_uint_t t = 0; 00939 int8_t d; 00940 00941 x += u8g->font_calc_vref(u8g); 00942 00943 while( *s != '\0' ) 00944 { 00945 d = u8g_DrawGlyph270(u8g, x, y, u8g_pgm_read(s)); 00946 y -= d; 00947 t += d; 00948 s++; 00949 } 00950 return t; 00951 } 00952 00953 u8g_uint_t u8g_DrawStrFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, const char *s) 00954 { 00955 x -= u8g_GetFontBBXOffX(u8g); 00956 y += u8g_GetFontBBXOffY(u8g); 00957 return u8g_DrawStrDir(u8g, x, y, dir, s); 00958 } 00959 00960 /* still used by picgen.c, dir argument is ignored */ 00961 int8_t u8g_DrawGlyphFontBBX(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t dir, uint8_t encoding) 00962 { 00963 x -= u8g_GetFontBBXOffX(u8g); 00964 y += u8g_GetFontBBXOffY(u8g); 00965 u8g_draw_glyph(u8g, x, y, encoding); 00966 return 0; 00967 } 00968 00969 00970 /*========================================================================*/ 00971 /* set ascent/descent for reference point calculation */ 00972 00973 void u8g_UpdateRefHeight(u8g_t *u8g) 00974 { 00975 uint16_t ls; 00976 if ( u8g->font == NULL ) 00977 return; 00978 if ( u8g->font_height_mode == U8G_FONT_HEIGHT_MODE_TEXT ) 00979 { 00980 u8g->font_ref_ascent = u8g_font_GetCapitalAHeight(u8g->font); 00981 u8g->font_ref_descent = u8g_font_GetLowerGDescent(u8g->font); 00982 } 00983 else if ( u8g->font_height_mode == U8G_FONT_HEIGHT_MODE_XTEXT ) 00984 { 00985 u8g->font_ref_ascent = u8g_font_GetFontXAscent(u8g->font); 00986 u8g->font_ref_descent = u8g_font_GetFontXDescent(u8g->font); 00987 } 00988 else 00989 { 00990 u8g->font_ref_ascent = u8g_font_GetFontAscent(u8g->font); 00991 u8g->font_ref_descent = u8g_font_GetFontDescent(u8g->font); 00992 } 00993 00994 ls = u8g->font_ref_ascent - u8g->font_ref_descent; 00995 if ( u8g->font_line_spacing_factor != 64 ) 00996 { 00997 ls &= 255; 00998 ls *= u8g->font_line_spacing_factor; 00999 ls >>= 6; 01000 } 01001 u8g->line_spacing = ls; 01002 } 01003 01004 void u8g_SetFontRefHeightText(u8g_t *u8g) 01005 { 01006 u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_TEXT; 01007 u8g_UpdateRefHeight(u8g); 01008 } 01009 01010 void u8g_SetFontRefHeightExtendedText(u8g_t *u8g) 01011 { 01012 u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_XTEXT; 01013 u8g_UpdateRefHeight(u8g); 01014 } 01015 01016 01017 void u8g_SetFontRefHeightAll(u8g_t *u8g) 01018 { 01019 u8g->font_height_mode = U8G_FONT_HEIGHT_MODE_ALL; 01020 u8g_UpdateRefHeight(u8g); 01021 } 01022 01023 /* factor = 64: linespaceing == ascent and descent */ 01024 void u8g_SetFontLineSpacingFactor(u8g_t *u8g, uint8_t factor) 01025 { 01026 u8g->font_line_spacing_factor = factor; 01027 u8g_UpdateRefHeight(u8g); 01028 } 01029 01030 01031 01032 /*========================================================================*/ 01033 /* callback procedures to correct the y position */ 01034 01035 u8g_uint_t u8g_font_calc_vref_font(u8g_t *u8g) 01036 { 01037 return 0; 01038 } 01039 01040 void u8g_SetFontPosBaseline(u8g_t *u8g) 01041 { 01042 u8g->font_calc_vref = u8g_font_calc_vref_font; 01043 } 01044 01045 01046 u8g_uint_t u8g_font_calc_vref_bottom(u8g_t *u8g) 01047 { 01048 /* y += (u8g_uint_t)(u8g_int_t)(u8g->font_ref_descent); */ 01049 return (u8g_uint_t)(u8g_int_t)(u8g->font_ref_descent); 01050 } 01051 01052 void u8g_SetFontPosBottom(u8g_t *u8g) 01053 { 01054 u8g->font_calc_vref = u8g_font_calc_vref_bottom; 01055 } 01056 01057 u8g_uint_t u8g_font_calc_vref_top(u8g_t *u8g) 01058 { 01059 u8g_uint_t tmp; 01060 /* reference pos is one pixel above the upper edge of the reference glyph */ 01061 01062 /* 01063 y += (u8g_uint_t)(u8g_int_t)(u8g->font_ref_ascent); 01064 y++; 01065 */ 01066 tmp = (u8g_uint_t)(u8g_int_t)(u8g->font_ref_ascent); 01067 tmp++; 01068 return tmp; 01069 } 01070 01071 void u8g_SetFontPosTop(u8g_t *u8g) 01072 { 01073 u8g->font_calc_vref = u8g_font_calc_vref_top; 01074 } 01075 01076 u8g_uint_t u8g_font_calc_vref_center(u8g_t *u8g) 01077 { 01078 int8_t tmp; 01079 tmp = u8g->font_ref_ascent; 01080 tmp -= u8g->font_ref_descent; 01081 tmp /= 2; 01082 tmp += u8g->font_ref_descent; 01083 /* y += (u8g_uint_t)(u8g_int_t)(tmp); */ 01084 return tmp; 01085 } 01086 01087 void u8g_SetFontPosCenter(u8g_t *u8g) 01088 { 01089 u8g->font_calc_vref = u8g_font_calc_vref_center; 01090 } 01091 01092 /*========================================================================*/ 01093 /* string pixel width calculation */ 01094 01095 char u8g_font_get_char(const void *s) 01096 { 01097 return *(const char *)(s); 01098 } 01099 01100 char u8g_font_get_charP(const void *s) 01101 { 01102 return u8g_pgm_read(s); 01103 } 01104 01105 typedef char (*u8g_font_get_char_fn)(const void *s); 01106 01107 01108 u8g_uint_t u8g_font_calc_str_pixel_width(u8g_t *u8g, const char *s, u8g_font_get_char_fn get_char ) 01109 { 01110 u8g_uint_t w; 01111 uint8_t enc; 01112 01113 /* reset the total minimal width to zero, this will be expanded during calculation */ 01114 w = 0; 01115 01116 enc = get_char(s); 01117 01118 /* check for empty string, width is already 0 */ 01119 if ( enc == '\0' ) 01120 { 01121 return w; 01122 } 01123 01124 /* get the glyph information of the first char. This must be valid, because we already checked for the empty string */ 01125 /* if *s is not inside the font, then the cached parameters of the glyph are all zero */ 01126 u8g_GetGlyph(u8g, enc); 01127 01128 /* strlen(s) == 1: width = width(s[0]) */ 01129 /* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */ 01130 /* strlen(s) == 3: width = - offx(s[0]) + deltax(s[0]) + deltax(s[1]) + offx(s[2]) + width(s[2]) */ 01131 01132 /* assume that the string has size 2 or more, than start with negative offset-x */ 01133 /* for string with size 1, this will be nullified after the loop */ 01134 w = -u8g->glyph_x; 01135 for(;;) 01136 { 01137 01138 /* check and stop if the end of the string is reached */ 01139 s++; 01140 if ( get_char(s) == '\0' ) 01141 break; 01142 01143 /* if there are still more characters, add the delta to the next glyph */ 01144 w += u8g->glyph_dx; 01145 01146 /* store the encoding in a local variable, used also after the for(;;) loop */ 01147 enc = get_char(s); 01148 01149 /* load the next glyph information */ 01150 u8g_GetGlyph(u8g, enc); 01151 } 01152 01153 /* finally calculate the width of the last char */ 01154 /* here is another exception, if the last char is a black, use the dx value instead */ 01155 if ( enc != ' ' ) 01156 { 01157 /* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */ 01158 w += u8g->glyph_width; 01159 w += u8g->glyph_x; 01160 } 01161 else 01162 { 01163 w += u8g->glyph_dx; 01164 } 01165 01166 01167 return w; 01168 } 01169 01170 u8g_uint_t u8g_GetStrPixelWidth(u8g_t *u8g, const char *s) 01171 { 01172 return u8g_font_calc_str_pixel_width(u8g, s, u8g_font_get_char); 01173 } 01174 01175 u8g_uint_t u8g_GetStrPixelWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s) 01176 { 01177 return u8g_font_calc_str_pixel_width(u8g, (const char *)s, u8g_font_get_charP); 01178 } 01179 01180 int8_t u8g_GetStrX(u8g_t *u8g, const char *s) 01181 { 01182 u8g_GetGlyph(u8g, *s); 01183 return u8g->glyph_x; 01184 } 01185 01186 int8_t u8g_GetStrXP(u8g_t *u8g, const u8g_pgm_uint8_t *s) 01187 { 01188 u8g_GetGlyph(u8g, u8g_pgm_read(s)); 01189 return u8g->glyph_x; 01190 } 01191 01192 /*========================================================================*/ 01193 /* string width calculation */ 01194 01195 u8g_uint_t u8g_GetStrWidth(u8g_t *u8g, const char *s) 01196 { 01197 u8g_uint_t w; 01198 uint8_t encoding; 01199 01200 /* reset the total width to zero, this will be expanded during calculation */ 01201 w = 0; 01202 01203 for(;;) 01204 { 01205 encoding = *s; 01206 if ( encoding == 0 ) 01207 break; 01208 01209 /* load glyph information */ 01210 u8g_GetGlyph(u8g, encoding); 01211 w += u8g->glyph_dx; 01212 01213 /* goto next char */ 01214 s++; 01215 } 01216 01217 return w; 01218 } 01219 01220 01221 u8g_uint_t u8g_GetStrWidthP(u8g_t *u8g, const u8g_pgm_uint8_t *s) 01222 { 01223 u8g_uint_t w; 01224 uint8_t encoding; 01225 01226 /* reset the total width to zero, this will be expanded during calculation */ 01227 w = 0; 01228 01229 for(;;) 01230 { 01231 encoding = u8g_pgm_read(s); 01232 if ( encoding == 0 ) 01233 break; 01234 01235 /* load glyph information */ 01236 u8g_GetGlyph(u8g, encoding); 01237 w += u8g->glyph_dx; 01238 01239 /* goto next char */ 01240 s++; 01241 } 01242 01243 return w; 01244 } 01245 01246 01247 /*========================================================================*/ 01248 /* calculation of font/glyph/string characteristics */ 01249 01250 01251 /* 01252 Description: 01253 Calculate parameter for the minimal bounding box on a given string 01254 Output 01255 buf->y_min extend of the lower left edge if the string below (y_min<0) or above (y_min>0) baseline (descent) 01256 buf->y_max extend of the upper left edge if the string below (y_min<0) or above (y_min>0) baseline (ascent) 01257 buf->w the width of the string 01258 */ 01259 struct u8g_str_size_struct 01260 { 01261 int8_t y_min; /* descent */ 01262 int8_t y_max; /* ascent */ 01263 int8_t x, y; /* the reference point of the font (negated!) */ 01264 u8g_uint_t w; /* width of the overall string */ 01265 }; 01266 typedef struct u8g_str_size_struct u8g_str_size_t; 01267 01268 static void u8g_font_calc_str_min_box(u8g_t *u8g, const char *s, u8g_str_size_t *buf) 01269 { 01270 /* u8g_glyph_t g; */ 01271 int8_t tmp; 01272 01273 /* reset the total minimal width to zero, this will be expanded during calculation */ 01274 buf->w = 0; 01275 01276 /* check for empty string, width is already 0, but also reset y_min and y_max to 0 */ 01277 if ( *s == '\0' ) 01278 { 01279 buf->y_min = 0; 01280 buf->y_max = 0; 01281 buf->x = 0; 01282 buf->y = 0; 01283 return; 01284 } 01285 01286 /* reset y_min to the largest possible value. Later we search for the smallest value */ 01287 /* y_min contains the position [pixel] of the lower left edge of the glyph above (y_min>0) or below (y_min<0) baseline */ 01288 buf->y_min = 127; 01289 /* reset y_max to the smallest possible value. Later we search for the highest value */ 01290 /* y_max contains the position [pixel] of the upper left edge of the glyph above (y_max>0) or below (y_max<0) baseline */ 01291 buf->y_max = -128; 01292 01293 /* get the glyph information of the first char. This must be valid, because we already checked for the empty string */ 01294 u8g_GetGlyph(u8g, *s); 01295 01296 /* strlen(s) == 1: width = width(s[0]) */ 01297 /* strlen(s) == 2: width = - offx(s[0]) + deltax(s[0]) + offx(s[1]) + width(s[1]) */ 01298 /* strlen(s) == 3: width = - offx(s[0]) + deltax(s[0]) + deltax(s[1]) + offx(s[2]) + width(s[2]) */ 01299 01300 /* assume that the string has size 2 or more, than start with negative offset-x */ 01301 /* for string with size 1, this will be nullified after the loop */ 01302 // buf->w = - u8g_font_GetGlyphBBXOffX(u8g->font, g); 01303 buf->w = - u8g->glyph_x; 01304 01305 /* Also copy the position of the first glyph. This is the reference point of the string (negated) */ 01306 buf->x = u8g->glyph_x; 01307 buf->y = u8g->glyph_y; 01308 01309 for(;;) 01310 { 01311 01312 /* calculated y position of the upper left corner (y_max) and lower left corner (y_min) of the string */ 01313 /* relative to the base line */ 01314 01315 tmp = u8g->glyph_y; 01316 if ( buf->y_min > tmp ) 01317 buf->y_min = tmp; 01318 01319 tmp +=u8g->glyph_height; 01320 if ( buf->y_max < tmp ) 01321 buf->y_max = tmp; 01322 01323 /* check and stop if the end of the string is reached */ 01324 s++; 01325 if ( *s == '\0' ) 01326 break; 01327 01328 /* if there are still more characters, add the delta to the next glyph */ 01329 buf->w += u8g->glyph_dx; 01330 01331 /* load the next glyph information */ 01332 u8g_GetGlyph(u8g, *s); 01333 } 01334 01335 /* finally calculate the width of the last char */ 01336 /* if g was not updated in the for loop (strlen() == 1), then the initial offset x gets removed */ 01337 buf->w += u8g->glyph_width; 01338 // buf->w += u8g_font_GetGlyphBBXOffX(u8g->font, g); 01339 01340 buf->w += u8g->glyph_x; 01341 } 01342 01343 /* calculate minimal box */ 01344 void u8g_font_box_min(u8g_t *u8g, const char *s, u8g_str_size_t *buf) 01345 { 01346 u8g_font_calc_str_min_box(u8g, s, buf); 01347 } 01348 01349 /* calculate gA box, but do not calculate the overall width */ 01350 void u8g_font_box_left_gA(u8g_t *u8g, const char *s, u8g_str_size_t *buf) 01351 { 01352 01353 } 01354 01355 /* calculate gA box, including overall width */ 01356 void u8g_font_box_all_gA(u8g_t *u8g, const char *s, u8g_str_size_t *buf) 01357 { 01358 01359 } 01360 01361 01362 static void u8g_font_get_str_box_fill_args(u8g_t *u8g, const char *s, u8g_str_size_t *buf, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) 01363 { 01364 /* 01365 u8g_glyph_t g; 01366 g = 01367 */ 01368 u8g_GetGlyph(u8g, *s); 01369 *x += u8g->glyph_x; 01370 *width = buf->w; 01371 *y -= buf->y_max; 01372 /* +1 because y_max is a height, this compensates the next step */ 01373 //*y += 1; 01374 /* because the reference point is one below the string, this compensates the previous step */ 01375 //*y -= 1; 01376 *height = buf->y_max; 01377 *height -= buf->y_min; 01378 } 01379 01380 01381 void u8g_GetStrMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) 01382 { 01383 u8g_str_size_t buf; 01384 01385 if ( *s == '\0' ) 01386 { 01387 *width= 0; 01388 *height = 0; 01389 return; 01390 } 01391 01392 u8g_font_calc_str_min_box(u8g, s, &buf); 01393 u8g_font_get_str_box_fill_args(u8g, s, &buf, x, y, width, height); 01394 } 01395 01396 01397 void u8g_GetStrAMinBox(u8g_t *u8g, const char *s, u8g_uint_t *x, u8g_uint_t *y, u8g_uint_t *width, u8g_uint_t *height) 01398 { 01399 u8g_str_size_t buf; 01400 uint8_t cap_a; 01401 01402 if ( *s == '\0' ) 01403 { 01404 *width= 0; 01405 *height = 0; 01406 return; 01407 } 01408 01409 cap_a = u8g_font_GetCapitalAHeight(u8g->font); 01410 u8g_font_calc_str_min_box(u8g, s, &buf); 01411 if ( buf.y_max < cap_a ) 01412 buf.y_max = cap_a; 01413 u8g_font_get_str_box_fill_args(u8g, s, &buf, x, y, width, height); 01414 } 01415 01416 void u8g_SetFont(u8g_t *u8g, const u8g_fntpgm_uint8_t *font) 01417 { 01418 if ( u8g->font != font ) 01419 { 01420 u8g->font = font; 01421 u8g_UpdateRefHeight(u8g); 01422 u8g_SetFontPosBaseline(u8g); 01423 } 01424 } 01425 01426 /*========================================================================*/ 01427 /* anti aliasing fonts */ 01428 01429 int8_t u8g_draw_aa_glyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 01430 { 01431 const u8g_pgm_uint8_t *data; 01432 uint8_t w, h; 01433 uint8_t i, j; 01434 u8g_uint_t ix, iy; 01435 01436 { 01437 u8g_glyph_t g = u8g_GetGlyph(u8g, encoding); 01438 if ( g == NULL ) 01439 return 0; 01440 data = u8g_font_GetGlyphDataStart(u8g->font, g); 01441 } 01442 01443 w = u8g->glyph_width; 01444 h = u8g->glyph_height; 01445 01446 x += u8g->glyph_x; 01447 y -= u8g->glyph_y; 01448 y--; 01449 01450 if ( u8g_IsBBXIntersection(u8g, x, y-h+1, w, h) == 0 ) 01451 return u8g->glyph_dx; 01452 01453 /* now, w is reused as bytes per line */ 01454 w += 3; 01455 w /= 4; 01456 01457 iy = y; 01458 iy -= h; 01459 iy++; 01460 01461 for( j = 0; j < h; j++ ) 01462 { 01463 ix = x; 01464 for( i = 0; i < w; i++ ) 01465 { 01466 u8g_Draw4TPixel(u8g, ix, iy, 0, u8g_pgm_read(data)); 01467 data++; 01468 ix+=4; 01469 } 01470 iy++; 01471 } 01472 return u8g->glyph_dx; 01473 } 01474 01475 int8_t u8g_DrawAAGlyph(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, uint8_t encoding) 01476 { 01477 y += u8g->font_calc_vref(u8g); 01478 return u8g_draw_aa_glyph(u8g, x, y, encoding); 01479 } 01480 01481 u8g_uint_t u8g_DrawAAStr(u8g_t *u8g, u8g_uint_t x, u8g_uint_t y, const char *s) 01482 { 01483 u8g_uint_t t = 0; 01484 int8_t d; 01485 01486 if ( u8g_font_GetFormat(u8g->font) != 2 ) 01487 return 0; 01488 //u8g_uint_t u8g_GetStrWidth(u8g, s); 01489 //u8g_font_GetFontAscent(u8g->font)-u8g_font_GetFontDescent(u8g->font); 01490 01491 y += u8g->font_calc_vref(u8g); 01492 01493 while( *s != '\0' ) 01494 { 01495 d = u8g_draw_aa_glyph(u8g, x, y, *s); 01496 x += d; 01497 t += d; 01498 s++; 01499 } 01500 return t; 01501 } 01502
Generated on Tue Jul 12 2022 17:30:57 by
 1.7.2
 1.7.2