iforce2d Chris / Mbed 2 deprecated ubxDistanceMeter

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers u8g_font.c Source File

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