Skip to content

Commit

Permalink
Merge pull request #21 from lovyan03/lgfx
Browse files Browse the repository at this point in the history
dispose pgm_read function
  • Loading branch information
tobozo authored May 17, 2020
2 parents 9c90d35 + 2173b84 commit b8e9d12
Show file tree
Hide file tree
Showing 21 changed files with 1,662 additions and 1,622 deletions.
91 changes: 34 additions & 57 deletions src/Fonts/lgfx_fonts.cpp
Original file line number Diff line number Diff line change
@@ -1,110 +1,87 @@
#include "lgfx_fonts.hpp"

#include <stdint.h>
#include <stddef.h>

#ifdef ARDUINO
#ifdef ESP_PLATFORM
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
#endif
#include <cstdint>
#include <cstddef>

#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) ({ decltype(addr) _addr = (addr); *(const unsigned short *)(_addr); })
#define pgm_read_dword(addr) ({ decltype(addr) _addr = (addr); *(const unsigned long *)(_addr); })
#define pgm_read_float(addr) ({ decltype(addr) _addr = (addr); *(const float *)(_addr); })
#define pgm_read_ptr(addr) ({ decltype(addr) _addr = (addr); *(void * const *)(_addr); })
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_ptr_near(addr) pgm_read_ptr(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)
#define PROGMEM
#ifndef PROGMEM
#define PROGMEM
#endif

namespace lgfx {
bool GLCDfont::updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const {
bool GLCDfont::updateFontMetric(FontMetrics*, std::uint16_t uniCode) const {
return uniCode < 256;
}

bool BMPfont::updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const {
bool BMPfont::updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const {
if ((uniCode -= 32) >= 96) return false;
metrics->x_advance = metrics->width = pgm_read_byte( (uint8_t *)pgm_read_dword( &widthtbl ) + uniCode );
metrics->x_advance = metrics->width = widthtbl[uniCode];
return true;
}

bool BDFfont::updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const {
metrics->x_advance = metrics->width = pgm_read_byte( (uniCode < 0x0100) ? &halfwidth : &width );
bool BDFfont::updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const {
metrics->x_advance = metrics->width = (uniCode < 0x0100) ? halfwidth : width;
return true;
}
}

//----------------------------------------------------------------------------

bool GFXfont::updateFontMetric(lgfx::FontMetrics *metrics, uint16_t uniCode) const {
bool GFXfont::updateFontMetric(lgfx::FontMetrics *metrics, std::uint16_t uniCode) const {
auto glyph = getGlyph(uniCode);
if (!glyph) return false;
metrics->x_offset = (int8_t)pgm_read_byte(&glyph->xOffset);
metrics->width = pgm_read_byte(&glyph->width);
metrics->x_advance = pgm_read_byte(&glyph->xAdvance);
metrics->x_offset = glyph->xOffset;
metrics->width = glyph->width;
metrics->x_advance = glyph->xAdvance;
return true;
}

GFXglyph* GFXfont::getGlyph(uint16_t uniCode) const {
if (uniCode > pgm_read_word(&last )
|| uniCode < pgm_read_word(&first)) return nullptr;
uint16_t custom_range_num = pgm_read_word(&range_num);
GFXglyph* GFXfont::getGlyph(std::uint16_t uniCode) const {
if (uniCode > last
|| uniCode < first) return nullptr;
std::uint16_t custom_range_num = range_num;
if (custom_range_num == 0) {
uniCode -= pgm_read_word(&first);
return &(((GFXglyph *)pgm_read_dword(&glyph))[uniCode]);
uniCode -= first;
return &glyph[uniCode];
}
auto range_pst = (EncodeRange*)pgm_read_dword(&range);
auto range_pst = range;
size_t i = 0;
while ((uniCode > pgm_read_word(&range_pst[i].end))
|| (uniCode < pgm_read_word(&range_pst[i].start))) {
while ((uniCode > range_pst[i].end)
|| (uniCode < range_pst[i].start)) {
if (++i == custom_range_num) return nullptr;
}
uniCode -= pgm_read_word(&range_pst[i].start) - pgm_read_word(&range_pst[i].base);
return &(((GFXglyph *)pgm_read_dword(&glyph))[uniCode]);
uniCode -= range_pst[i].start - range_pst[i].base;
return &glyph[uniCode];
}

void GFXfont::getDefaultMetric(lgfx::FontMetrics *metrics) const {
int_fast8_t glyph_ab = 0; // glyph delta Y (height) above baseline
int_fast8_t glyph_bb = 0; // glyph delta Y (height) below baseline
size_t numChars = pgm_read_word(&last) - pgm_read_word(&first);
std::int_fast8_t glyph_ab = 0; // glyph delta Y (height) above baseline
std::int_fast8_t glyph_bb = 0; // glyph delta Y (height) below baseline
size_t numChars = last - first;

size_t custom_range_num = pgm_read_word(&range_num);
size_t custom_range_num = range_num;
if (custom_range_num != 0) {
EncodeRange *range_pst = (EncodeRange *)pgm_read_dword(&range);
EncodeRange *range_pst = range;
size_t i = 0;
numChars = custom_range_num;
do {
numChars += pgm_read_word(&range_pst[i].end) - pgm_read_word(&range_pst[i].start);
numChars += range_pst[i].end - range_pst[i].start;
} while (++i < custom_range_num);
}

// Find the biggest above and below baseline offsets
for (size_t c = 0; c < numChars; c++)
{
GFXglyph *glyph1 = &(((GFXglyph *)pgm_read_dword(&glyph))[c]);
int8_t ab = -pgm_read_byte(&glyph1->yOffset);
GFXglyph *glyph1 = &glyph[c];
std::int_fast8_t ab = -glyph1->yOffset;
if (ab > glyph_ab) glyph_ab = ab;
int8_t bb = pgm_read_byte(&glyph1->height) - ab;
std::int_fast8_t bb = glyph1->height - ab;
if (bb > glyph_bb) glyph_bb = bb;
}

metrics->baseline = glyph_ab;
metrics->y_offset = - glyph_ab;
metrics->height = glyph_bb + glyph_ab;
metrics->y_advance = (uint8_t)pgm_read_byte(&yAdvance);
metrics->y_advance = yAdvance;
}

//----------------------------------------------------------------------------
Expand Down
100 changes: 50 additions & 50 deletions src/Fonts/lgfx_fonts.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef LGFX_FONTS_HPP_
#define LGFX_FONTS_HPP_

#include <stdint.h>
#include <cstdint>

namespace lgfx
{
enum textdatum_t : uint8_t
enum textdatum_t : std::uint8_t
// 0:left 1:centre 2:right
// 0:top 4:middle 8:bottom 16:baseline
{ top_left = 0 // Top left (default)
Expand All @@ -27,20 +27,20 @@ namespace lgfx
};

struct FontMetrics {
int16_t width;
int16_t x_advance;
int16_t x_offset;
int16_t height;
int16_t y_advance;
int16_t y_offset;
int16_t baseline;
std::int16_t width;
std::int16_t x_advance;
std::int16_t x_offset;
std::int16_t height;
std::int16_t y_advance;
std::int16_t y_offset;
std::int16_t baseline;
};

struct TextStyle {
uint32_t fore_rgb888 = 0xFFFFFFU;
uint32_t back_rgb888 = 0;
int_fast8_t size_x = 1;
int_fast8_t size_y = 1;
std::uint32_t fore_rgb888 = 0xFFFFFFU;
std::uint32_t back_rgb888 = 0;
std::int_fast8_t size_x = 1;
std::int_fast8_t size_y = 1;
textdatum_t datum = textdatum_t::top_left;
bool utf8 = true;
bool cp437 = false;
Expand All @@ -60,7 +60,7 @@ namespace lgfx

virtual font_type_t getType(void) const = 0;
virtual void getDefaultMetric(FontMetrics *metrics) const = 0;
virtual bool updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const = 0;
virtual bool updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const = 0;
virtual bool unloadFont(void) { return false; }
/*
struct param {
Expand All @@ -79,13 +79,13 @@ namespace lgfx
};

struct BaseFont : public IFont {
const uint8_t *chartbl;
const uint8_t *widthtbl;
const uint8_t width;
const uint8_t height;
const uint8_t baseline;
const std::uint8_t *chartbl;
const std::uint8_t *widthtbl;
const std::uint8_t width;
const std::uint8_t height;
const std::uint8_t baseline;
BaseFont() = default;
constexpr BaseFont(const uint8_t *chartbl, const uint8_t *widthtbl, uint8_t width, uint8_t height, uint8_t baseline)
constexpr BaseFont(const std::uint8_t *chartbl, const std::uint8_t *widthtbl, std::uint8_t width, std::uint8_t height, std::uint8_t baseline)
: chartbl (chartbl )
, widthtbl (widthtbl )
, width (width )
Expand All @@ -104,38 +104,38 @@ namespace lgfx
};

struct GLCDfont : public BaseFont {
constexpr GLCDfont(const uint8_t *chartbl, const uint8_t *widthtbl, uint8_t width, uint8_t height, uint8_t baseline) : BaseFont(chartbl, widthtbl, width, height, baseline ) {}
constexpr GLCDfont(const std::uint8_t *chartbl, const std::uint8_t *widthtbl, std::uint8_t width, std::uint8_t height, std::uint8_t baseline) : BaseFont(chartbl, widthtbl, width, height, baseline ) {}
constexpr font_type_t getType(void) const override { return ft_glcd; }

bool updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const override;
bool updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const override;
};

struct BMPfont : public BaseFont {
constexpr BMPfont(const uint8_t *chartbl, const uint8_t *widthtbl, uint8_t width, uint8_t height, uint8_t baseline) : BaseFont(chartbl, widthtbl, width, height, baseline ) {}
constexpr BMPfont(const std::uint8_t *chartbl, const std::uint8_t *widthtbl, std::uint8_t width, std::uint8_t height, std::uint8_t baseline) : BaseFont(chartbl, widthtbl, width, height, baseline ) {}
constexpr font_type_t getType(void) const override { return ft_bmp; }

bool updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const override;
bool updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const override;
};

struct RLEfont : public BMPfont {
constexpr RLEfont(const uint8_t *chartbl, const uint8_t *widthtbl, uint8_t width, uint8_t height, uint8_t baseline) : BMPfont(chartbl, widthtbl, width, height, baseline ) {}
constexpr RLEfont(const std::uint8_t *chartbl, const std::uint8_t *widthtbl, std::uint8_t width, std::uint8_t height, std::uint8_t baseline) : BMPfont(chartbl, widthtbl, width, height, baseline ) {}
constexpr font_type_t getType(void) const override { return ft_rle; }
};

struct BDFfont : public BaseFont {
const uint16_t *indextbl;
uint16_t indexsize;
uint8_t halfwidth;
const std::uint16_t *indextbl;
std::uint16_t indexsize;
std::uint8_t halfwidth;
BDFfont() = default;
constexpr BDFfont(const uint8_t *chartbl, const uint16_t *indextbl, uint16_t indexsize, uint8_t width, uint8_t halfwidth, uint8_t height, uint8_t baseline)
constexpr BDFfont(const std::uint8_t *chartbl, const std::uint16_t *indextbl, std::uint16_t indexsize, std::uint8_t width, std::uint8_t halfwidth, std::uint8_t height, std::uint8_t baseline)
: BaseFont(chartbl, nullptr, width, height, baseline )
, indextbl(indextbl)
, indexsize(indexsize)
, halfwidth(halfwidth)
{}
constexpr font_type_t getType(void) const override { return ft_bdf; }

bool updateFontMetric(FontMetrics *metrics, uint16_t uniCode) const override;
bool updateFontMetric(FontMetrics *metrics, std::uint16_t uniCode) const override;
};

// deprecated array.
Expand All @@ -145,33 +145,33 @@ namespace lgfx
// Adafruit GFX font

struct GFXglyph { // Data stored PER GLYPH
uint32_t bitmapOffset; // Pointer into GFXfont->bitmap
uint8_t width, height; // Bitmap dimensions in pixels
uint8_t xAdvance; // Distance to advance cursor (x axis)
int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
std::uint32_t bitmapOffset; // Pointer into GFXfont->bitmap
std::uint8_t width, height; // Bitmap dimensions in pixels
std::uint8_t xAdvance; // Distance to advance cursor (x axis)
std::int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
};

struct GFXfont : public lgfx::IFont { // Data stored for FONT AS A WHOLE:
struct EncodeRange {
uint16_t start;
uint16_t end;
uint16_t base;
std::uint16_t start;
std::uint16_t end;
std::uint16_t base;
};

uint8_t *bitmap; // Glyph bitmaps, concatenated
std::uint8_t *bitmap; // Glyph bitmaps, concatenated
GFXglyph *glyph; // Glyph array
uint16_t first, last; // ASCII extents
uint8_t yAdvance; // Newline distance (y axis)
std::uint16_t first, last; // ASCII extents
std::uint8_t yAdvance; // Newline distance (y axis)

uint16_t range_num; // Number of EncodeRange
std::uint16_t range_num; // Number of EncodeRange
EncodeRange *range; // Array ofEncodeRange

constexpr GFXfont ( uint8_t *bitmap
constexpr GFXfont ( std::uint8_t *bitmap
, GFXglyph *glyph
, uint16_t first
, uint16_t last
, uint8_t yAdvance
, uint16_t range_num = 0
, std::uint16_t first
, std::uint16_t last
, std::uint8_t yAdvance
, std::uint16_t range_num = 0
, EncodeRange *range = nullptr
)
: bitmap (bitmap )
Expand All @@ -183,25 +183,25 @@ namespace lgfx
, range (range )
{}

GFXglyph* getGlyph(uint16_t uniCode) const;
GFXglyph* getGlyph(std::uint16_t uniCode) const;

constexpr font_type_t getType(void) const override { return font_type_t::ft_gfx; }

void getDefaultMetric(lgfx::FontMetrics *metrics) const;

bool updateFontMetric(lgfx::FontMetrics *metrics, uint16_t uniCode) const override;
bool updateFontMetric(lgfx::FontMetrics *metrics, std::uint16_t uniCode) const override;
};


//----------------------------------------------------------------------------

namespace fonts {
#ifdef __EFONT_FONT_DATA_H__
static constexpr lgfx::BDFfont efont = { (const uint8_t *)efontFontData, efontFontList, sizeof(efontFontList)>>1, 16, 8, 16, 14 };
static constexpr lgfx::BDFfont efont = { (const std::uint8_t *)efontFontData, efontFontList, sizeof(efontFontList)>>1, 16, 8, 16, 14 };
#endif

#ifdef misakiUTF16FontData_h
static constexpr lgfx::BDFfont misaki = { (const uint8_t *)fdata, ftable, sizeof(ftable)>>1, 8, 4, 7, 6 };
static constexpr lgfx::BDFfont misaki = { (const std::uint8_t *)fdata, ftable, sizeof(ftable)>>1, 8, 4, 7, 6 };
#endif

extern const lgfx::GLCDfont Font0;
Expand Down
Loading

0 comments on commit b8e9d12

Please sign in to comment.