WIP: compiles but completely broken
AGG files imported from AGG repository, sdl-testing branch. the pixfmt_bgra32_lcd is just implemented and is not tested.
This commit is contained in:
parent
79487074c0
commit
23a080ca45
|
@ -1,4 +1,4 @@
|
||||||
project('lite', 'c', version: '1.05', default_options : ['c_std=gnu11'])
|
project('lite', 'c', 'cpp', version: '1.05', default_options : ['c_std=gnu11', 'cpp_std=c++03'])
|
||||||
|
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
libm = cc.find_library('m', required : false)
|
libm = cc.find_library('m', required : false)
|
||||||
|
@ -6,6 +6,8 @@ libdl = cc.find_library('dl', required : false)
|
||||||
|
|
||||||
lua_dep = dependency('lua')
|
lua_dep = dependency('lua')
|
||||||
sdl_dep = dependency('sdl2', method: 'config-tool')
|
sdl_dep = dependency('sdl2', method: 'config-tool')
|
||||||
|
libagg_dep = dependency('libagg')
|
||||||
|
freetype_dep = dependency('freetype2')
|
||||||
stb_truetype_dep = dependency('stb_truetype')
|
stb_truetype_dep = dependency('stb_truetype')
|
||||||
|
|
||||||
lite_include = include_directories('src')
|
lite_include = include_directories('src')
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
stbtt_InitFont
|
||||||
|
|
||||||
|
stbtt_ScaleForMappingEmToPixels x 3
|
||||||
|
stbtt_ScaleForPixelHeight
|
||||||
|
stbtt_BakeFontBitmap
|
||||||
|
stbtt_GetFontVMetrics x 2
|
||||||
|
|
||||||
|
struct RenImage {
|
||||||
|
RenColor *pixels;
|
||||||
|
int width, height;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
RenImage *image;
|
||||||
|
stbtt_bakedchar glyphs[256];
|
||||||
|
} GlyphSet;
|
||||||
|
|
||||||
|
struct RenFont {
|
||||||
|
void *data;
|
||||||
|
stbtt_fontinfo stbfont;
|
||||||
|
GlyphSet *sets[MAX_GLYPHSET];
|
||||||
|
float size;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap
|
||||||
|
float xoff, yoff, xadvance;
|
||||||
|
} stbtt_bakedchar;
|
||||||
|
|
||||||
|
The function stbtt_BakeFontBitmap is used to write bitmap data into set->image->pixels (where set is a GlyphSet).
|
||||||
|
Note that set->image->pixels need data in RGB format. After stbtt_BakeFontBitmap call the bitmap data are converted into RGB.
|
||||||
|
With a single call many glyphs corresponding to a range of codepoints, all in a
|
||||||
|
single image.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,196 @@
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Anti-Grain Geometry - Version 2.4
|
||||||
|
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
|
||||||
|
//
|
||||||
|
// Permission to copy, use, modify, sell and distribute this software
|
||||||
|
// is granted provided this copyright notice appears in all copies.
|
||||||
|
// This software is provided "as is" without express or implied
|
||||||
|
// warranty, and with no claim as to its suitability for any purpose.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Contact: mcseem@antigrain.com
|
||||||
|
// mcseemagg@yahoo.com
|
||||||
|
// http://www.antigrain.com
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// See implementation agg_font_freetype.cpp
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef AGG_FONT_FREETYPE_INCLUDED
|
||||||
|
#define AGG_FONT_FREETYPE_INCLUDED
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "agg_scanline_storage_aa.h"
|
||||||
|
#include "agg_scanline_storage_bin.h"
|
||||||
|
#include "agg_scanline_u.h"
|
||||||
|
#include "agg_scanline_bin.h"
|
||||||
|
#include "agg_path_storage_integer.h"
|
||||||
|
#include "agg_rasterizer_scanline_aa.h"
|
||||||
|
#include "agg_conv_curve.h"
|
||||||
|
#include "agg_font_cache_manager.h"
|
||||||
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
|
namespace agg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------font_engine_freetype_base
|
||||||
|
class font_engine_freetype_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
typedef serialized_scanlines_adaptor_aa<int8u> gray8_adaptor_type;
|
||||||
|
typedef serialized_scanlines_adaptor_bin mono_adaptor_type;
|
||||||
|
typedef scanline_storage_aa8 scanlines_aa_type;
|
||||||
|
typedef scanline_storage_bin scanlines_bin_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
~font_engine_freetype_base();
|
||||||
|
font_engine_freetype_base(bool flag32, unsigned max_faces = 32);
|
||||||
|
|
||||||
|
// Set font parameters
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void resolution(unsigned dpi);
|
||||||
|
bool load_font(const char* font_name, unsigned face_index, glyph_rendering ren_type,
|
||||||
|
const char* font_mem = 0, const long font_mem_size = 0);
|
||||||
|
bool attach(const char* file_name);
|
||||||
|
bool char_map(FT_Encoding map);
|
||||||
|
bool height(double h);
|
||||||
|
bool width(double w);
|
||||||
|
void hinting(bool h);
|
||||||
|
void flip_y(bool f);
|
||||||
|
void transform(const trans_affine& affine);
|
||||||
|
|
||||||
|
// Set Gamma
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
template<class GammaF> void gamma(const GammaF& f)
|
||||||
|
{
|
||||||
|
m_rasterizer.gamma(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accessors
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
int last_error() const { return m_last_error; }
|
||||||
|
unsigned resolution() const { return m_resolution; }
|
||||||
|
const char* name() const { return m_name; }
|
||||||
|
unsigned num_faces() const;
|
||||||
|
FT_Encoding char_map() const { return m_char_map; }
|
||||||
|
double height() const { return double(m_height) / 64.0; }
|
||||||
|
double width() const { return double(m_width) / 64.0; }
|
||||||
|
double ascender() const;
|
||||||
|
double descender() const;
|
||||||
|
bool hinting() const { return m_hinting; }
|
||||||
|
bool flip_y() const { return m_flip_y; }
|
||||||
|
|
||||||
|
|
||||||
|
// Interface mandatory to implement for font_cache_manager
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
const char* font_signature() const { return m_signature; }
|
||||||
|
int change_stamp() const { return m_change_stamp; }
|
||||||
|
|
||||||
|
bool prepare_glyph(unsigned glyph_code);
|
||||||
|
unsigned glyph_index() const { return m_glyph_index; }
|
||||||
|
unsigned data_size() const { return m_data_size; }
|
||||||
|
glyph_data_type data_type() const { return m_data_type; }
|
||||||
|
const rect_i& bounds() const { return m_bounds; }
|
||||||
|
double advance_x() const { return m_advance_x; }
|
||||||
|
double advance_y() const { return m_advance_y; }
|
||||||
|
void write_glyph_to(int8u* data) const;
|
||||||
|
bool add_kerning(unsigned first, unsigned second,
|
||||||
|
double* x, double* y);
|
||||||
|
|
||||||
|
private:
|
||||||
|
font_engine_freetype_base(const font_engine_freetype_base&);
|
||||||
|
const font_engine_freetype_base& operator = (const font_engine_freetype_base&);
|
||||||
|
|
||||||
|
void update_char_size();
|
||||||
|
void update_signature();
|
||||||
|
int find_face(const char* face_name) const;
|
||||||
|
|
||||||
|
bool m_flag32;
|
||||||
|
int m_change_stamp;
|
||||||
|
int m_last_error;
|
||||||
|
char* m_name;
|
||||||
|
unsigned m_name_len;
|
||||||
|
unsigned m_face_index;
|
||||||
|
FT_Encoding m_char_map;
|
||||||
|
char* m_signature;
|
||||||
|
unsigned m_height;
|
||||||
|
unsigned m_width;
|
||||||
|
bool m_hinting;
|
||||||
|
bool m_flip_y;
|
||||||
|
bool m_library_initialized;
|
||||||
|
FT_Library m_library; // handle to library
|
||||||
|
FT_Face* m_faces; // A pool of font faces
|
||||||
|
char** m_face_names;
|
||||||
|
unsigned m_num_faces;
|
||||||
|
unsigned m_max_faces;
|
||||||
|
FT_Face m_cur_face; // handle to the current face object
|
||||||
|
int m_resolution;
|
||||||
|
glyph_rendering m_glyph_rendering;
|
||||||
|
unsigned m_glyph_index;
|
||||||
|
unsigned m_data_size;
|
||||||
|
glyph_data_type m_data_type;
|
||||||
|
rect_i m_bounds;
|
||||||
|
double m_advance_x;
|
||||||
|
double m_advance_y;
|
||||||
|
trans_affine m_affine;
|
||||||
|
|
||||||
|
path_storage_integer<int16, 6> m_path16;
|
||||||
|
path_storage_integer<int32, 6> m_path32;
|
||||||
|
conv_curve<path_storage_integer<int16, 6> > m_curves16;
|
||||||
|
conv_curve<path_storage_integer<int32, 6> > m_curves32;
|
||||||
|
scanline_u8 m_scanline_aa;
|
||||||
|
scanline_bin m_scanline_bin;
|
||||||
|
scanlines_aa_type m_scanlines_aa;
|
||||||
|
scanlines_bin_type m_scanlines_bin;
|
||||||
|
rasterizer_scanline_aa<> m_rasterizer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------font_engine_freetype_int16
|
||||||
|
// This class uses values of type int16 (10.6 format) for the vector cache.
|
||||||
|
// The vector cache is compact, but when rendering glyphs of height
|
||||||
|
// more that 200 there integer overflow can occur.
|
||||||
|
//
|
||||||
|
class font_engine_freetype_int16 : public font_engine_freetype_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef serialized_integer_path_adaptor<int16, 6> path_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type;
|
||||||
|
typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;
|
||||||
|
|
||||||
|
font_engine_freetype_int16(unsigned max_faces = 32) :
|
||||||
|
font_engine_freetype_base(false, max_faces) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------font_engine_freetype_int32
|
||||||
|
// This class uses values of type int32 (26.6 format) for the vector cache.
|
||||||
|
// The vector cache is twice larger than in font_engine_freetype_int16,
|
||||||
|
// but it allows you to render glyphs of very large sizes.
|
||||||
|
//
|
||||||
|
class font_engine_freetype_int32 : public font_engine_freetype_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef serialized_integer_path_adaptor<int32, 6> path_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::gray8_adaptor_type gray8_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::mono_adaptor_type mono_adaptor_type;
|
||||||
|
typedef font_engine_freetype_base::scanlines_aa_type scanlines_aa_type;
|
||||||
|
typedef font_engine_freetype_base::scanlines_bin_type scanlines_bin_type;
|
||||||
|
|
||||||
|
font_engine_freetype_int32(unsigned max_faces = 32) :
|
||||||
|
font_engine_freetype_base(true, max_faces) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,274 @@
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Anti-Grain Geometry (AGG) - Version 2.5
|
||||||
|
// A high quality rendering engine for C++
|
||||||
|
// Copyright (C) 2002-2006 Maxim Shemanarev
|
||||||
|
// Contact: mcseem@antigrain.com
|
||||||
|
// mcseemagg@yahoo.com
|
||||||
|
// http://antigrain.com
|
||||||
|
//
|
||||||
|
// AGG is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// AGG is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with AGG; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
// MA 02110-1301, USA.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef AGG_PIXFMT_BGRA32_LCD_INCLUDED
|
||||||
|
#define AGG_PIXFMT_BGRA32_LCD_INCLUDED
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "agg_basics.h"
|
||||||
|
#include "agg_color_rgba.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
|
||||||
|
namespace agg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================lcd_distribution_lut
|
||||||
|
class lcd_distribution_lut
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcd_distribution_lut(double prim, double second, double tert)
|
||||||
|
{
|
||||||
|
double norm = 1.0 / (prim + second*2 + tert*2);
|
||||||
|
prim *= norm;
|
||||||
|
second *= norm;
|
||||||
|
tert *= norm;
|
||||||
|
for(unsigned i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
unsigned b = (i << 8);
|
||||||
|
unsigned s = round(second * b);
|
||||||
|
unsigned t = round(tert * b);
|
||||||
|
unsigned p = b - (2*s + 2*t);
|
||||||
|
|
||||||
|
m_data[3*i + 1] = s; /* secondary */
|
||||||
|
m_data[3*i + 2] = t; /* tertiary */
|
||||||
|
m_data[3*i ] = p; /* primary */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned convolution(const int8u* covers, int i0, int i_min, int i_max) const
|
||||||
|
{
|
||||||
|
unsigned sum = 0;
|
||||||
|
int k_min = (i0 >= i_min + 2 ? -2 : i_min - i0);
|
||||||
|
int k_max = (i0 <= i_max - 2 ? 2 : i_max - i0);
|
||||||
|
for (int k = k_min; k <= k_max; k++)
|
||||||
|
{
|
||||||
|
/* select the primary, secondary or tertiary channel */
|
||||||
|
int channel = abs(k) % 3;
|
||||||
|
int8u c = covers[i0 + k];
|
||||||
|
sum += m_data[3*c + channel];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum + 128) >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned short m_data[256*3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================pixfmt_bgra32_lcd
|
||||||
|
class pixfmt_bgra32_lcd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef rgba8 color_type;
|
||||||
|
typedef rendering_buffer::row_data row_data;
|
||||||
|
typedef color_type::value_type value_type;
|
||||||
|
typedef color_type::calc_type calc_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
pixfmt_bgra32_lcd(rendering_buffer& rb, const lcd_distribution_lut& lut)
|
||||||
|
: m_rbuf(&rb), m_lut(&lut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
unsigned width() const {
|
||||||
|
return m_rbuf->width() * 3;
|
||||||
|
}
|
||||||
|
unsigned height() const {
|
||||||
|
return m_rbuf->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method should never be called when using the scanline_u8.
|
||||||
|
// The use of scanline_p8 should be avoided because if does not works
|
||||||
|
// properly for rendering fonts because single hspan are split in many
|
||||||
|
// hline/hspan elements and pixel whitening happens.
|
||||||
|
void blend_hline(int x, int y, unsigned len,
|
||||||
|
const color_type& c, int8u cover)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||||
|
{
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x / 3) * 4;
|
||||||
|
for (int ilen = len; ilen > 0; p += 4, ilen -= 3)
|
||||||
|
{
|
||||||
|
p[0] = c.b;
|
||||||
|
p[1] = c.g;
|
||||||
|
p[2] = c.r;
|
||||||
|
p[3] = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void blend_solid_hspan(int x, int y,
|
||||||
|
unsigned len,
|
||||||
|
const color_type& c,
|
||||||
|
const int8u* covers)
|
||||||
|
{
|
||||||
|
unsigned rowlen = width();
|
||||||
|
int cx = (x - 2 >= 0 ? -2 : -x);
|
||||||
|
int cx_max = (len + 2 <= rowlen ? len + 1 : rowlen - 1);
|
||||||
|
|
||||||
|
int i = (x + cx) % 3;
|
||||||
|
|
||||||
|
const int8u rgb[3] = { c.r, c.g, c.b };
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x + cx);
|
||||||
|
|
||||||
|
const int pixel_index[3] = {2, 1, 0};
|
||||||
|
for (/* */; cx <= cx_max; cx += 3)
|
||||||
|
{
|
||||||
|
unsigned c_conv, alpha, dst_col, src_col;
|
||||||
|
c_conv = m_lut->convolution(covers, cx, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = rgb[i];
|
||||||
|
src_col = *(p + pixel_index[i]);
|
||||||
|
*(p + pixel_index[i]) = (int8u)((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
c_conv = m_lut->convolution(covers, cx + 1, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = rgb[i];
|
||||||
|
src_col = *(p + pixel_index[i]);
|
||||||
|
*(p + pixel_index[i]) = (int8u)((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
c_conv = m_lut->convolution(covers, cx + 2, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = rgb[i];
|
||||||
|
src_col = *(p + pixel_index[i]);
|
||||||
|
*(p + pixel_index[i]) = (int8u)((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
p[3] = 0xff;
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rendering_buffer* m_rbuf;
|
||||||
|
const lcd_distribution_lut* m_lut;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Gamma>
|
||||||
|
class pixfmt_bgra32_lcd_gamma
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef rgba8 color_type;
|
||||||
|
typedef rendering_buffer::row_data row_data;
|
||||||
|
typedef color_type::value_type value_type;
|
||||||
|
typedef color_type::calc_type calc_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
pixfmt_bgra32_lcd_gamma(rendering_buffer& rb, const lcd_distribution_lut& lut, const Gamma& gamma)
|
||||||
|
: m_rbuf(&rb), m_lut(&lut), m_gamma(gamma)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
unsigned width() const {
|
||||||
|
return m_rbuf->width() * 3;
|
||||||
|
}
|
||||||
|
unsigned height() const {
|
||||||
|
return m_rbuf->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method should never be called when using the scanline_u8.
|
||||||
|
// The use of scanline_p8 should be avoided because if does not works
|
||||||
|
// properly for rendering fonts because single hspan are split in many
|
||||||
|
// hline/hspan elements and pixel whitening happens.
|
||||||
|
void blend_hline(int x, int y, unsigned len,
|
||||||
|
const color_type& c, int8u cover)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||||
|
{
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x / 3) * 4;
|
||||||
|
for (int ilen = len; ilen > 0; p += 4, ilen -= 3)
|
||||||
|
{
|
||||||
|
p[0] = c.r;
|
||||||
|
p[1] = c.g;
|
||||||
|
p[2] = c.b;
|
||||||
|
p[3] = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void blend_solid_hspan(int x, int y,
|
||||||
|
unsigned len,
|
||||||
|
const color_type& c,
|
||||||
|
const int8u* covers)
|
||||||
|
{
|
||||||
|
unsigned rowlen = width();
|
||||||
|
int cx = (x - 2 >= 0 ? -2 : -x);
|
||||||
|
int cx_max = (len + 2 <= rowlen ? len + 1 : rowlen - 1);
|
||||||
|
|
||||||
|
int i = (x + cx) % 3;
|
||||||
|
|
||||||
|
const int8u rgb[3] = { c.r, c.g, c.b };
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x + cx);
|
||||||
|
|
||||||
|
const int pixel_index[3] = {2, 1, 0};
|
||||||
|
for (/* */; cx <= cx_max; cx += 3)
|
||||||
|
{
|
||||||
|
unsigned c_conv, alpha, dst_col, src_col;
|
||||||
|
c_conv = m_lut->convolution(covers, cx, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = m_gamma.dir(rgb[i]);
|
||||||
|
src_col = m_gamma.dir(*(p + pixel_index[i]));
|
||||||
|
*(p + pixel_index[i]) = m_gamma.inv((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
c_conv = m_lut->convolution(covers, cx + 1, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = m_gamma.dir(rgb[i]);
|
||||||
|
src_col = m_gamma.dir(*(p + pixel_index[i]));
|
||||||
|
*(p + pixel_index[i]) = m_gamma.inv((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
c_conv = m_lut->convolution(covers, cx + 2, 0, len - 1);
|
||||||
|
alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
dst_col = m_gamma.dir(rgb[i]);
|
||||||
|
src_col = m_gamma.dir(*(p + pixel_index[i]));
|
||||||
|
*(p + pixel_index[i]) = m_gamma.inv((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
|
||||||
|
p[3] = 0xff;
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rendering_buffer* m_rbuf;
|
||||||
|
const lcd_distribution_lut* m_lut;
|
||||||
|
const Gamma& m_gamma;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,238 @@
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Anti-Grain Geometry (AGG) - Version 2.5
|
||||||
|
// A high quality rendering engine for C++
|
||||||
|
// Copyright (C) 2002-2006 Maxim Shemanarev
|
||||||
|
// Contact: mcseem@antigrain.com
|
||||||
|
// mcseemagg@yahoo.com
|
||||||
|
// http://antigrain.com
|
||||||
|
//
|
||||||
|
// AGG is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// AGG is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with AGG; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
// MA 02110-1301, USA.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef AGG_PIXFMT_RGB24_LCD_INCLUDED
|
||||||
|
#define AGG_PIXFMT_RGB24_LCD_INCLUDED
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "agg_basics.h"
|
||||||
|
#include "agg_color_rgba.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
|
||||||
|
namespace agg
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
//=====================================================lcd_distribution_lut
|
||||||
|
class lcd_distribution_lut
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lcd_distribution_lut(double prim, double second, double tert)
|
||||||
|
{
|
||||||
|
double norm = 1.0 / (prim + second*2 + tert*2);
|
||||||
|
prim *= norm;
|
||||||
|
second *= norm;
|
||||||
|
tert *= norm;
|
||||||
|
for(unsigned i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
unsigned b = (i << 8);
|
||||||
|
unsigned s = round(second * b);
|
||||||
|
unsigned t = round(tert * b);
|
||||||
|
unsigned p = b - (2*s + 2*t);
|
||||||
|
|
||||||
|
m_data[3*i + 1] = s; /* secondary */
|
||||||
|
m_data[3*i + 2] = t; /* tertiary */
|
||||||
|
m_data[3*i ] = p; /* primary */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned convolution(const int8u* covers, int i0, int i_min, int i_max) const
|
||||||
|
{
|
||||||
|
unsigned sum = 0;
|
||||||
|
int k_min = (i0 >= i_min + 2 ? -2 : i_min - i0);
|
||||||
|
int k_max = (i0 <= i_max - 2 ? 2 : i_max - i0);
|
||||||
|
for (int k = k_min; k <= k_max; k++)
|
||||||
|
{
|
||||||
|
/* select the primary, secondary or tertiary channel */
|
||||||
|
int channel = abs(k) % 3;
|
||||||
|
int8u c = covers[i0 + k];
|
||||||
|
sum += m_data[3*c + channel];
|
||||||
|
}
|
||||||
|
|
||||||
|
return (sum + 128) >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned short m_data[256*3];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================pixfmt_rgb24_lcd
|
||||||
|
class pixfmt_rgb24_lcd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef rgba8 color_type;
|
||||||
|
typedef rendering_buffer::row_data row_data;
|
||||||
|
typedef color_type::value_type value_type;
|
||||||
|
typedef color_type::calc_type calc_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
pixfmt_rgb24_lcd(rendering_buffer& rb, const lcd_distribution_lut& lut)
|
||||||
|
: m_rbuf(&rb), m_lut(&lut)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
unsigned width() const {
|
||||||
|
return m_rbuf->width() * 3;
|
||||||
|
}
|
||||||
|
unsigned height() const {
|
||||||
|
return m_rbuf->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method should never be called when using the scanline_u8.
|
||||||
|
// The use of scanline_p8 should be avoided because if does not works
|
||||||
|
// properly for rendering fonts because single hspan are split in many
|
||||||
|
// hline/hspan elements and pixel whitening happens.
|
||||||
|
void blend_hline(int x, int y, unsigned len,
|
||||||
|
const color_type& c, int8u cover)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||||
|
{
|
||||||
|
int xr = x - (x % 3);
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + xr;
|
||||||
|
for (int ilen = len; ilen > 0; p += 3, ilen -= 3)
|
||||||
|
{
|
||||||
|
p[0] = c.r;
|
||||||
|
p[1] = c.g;
|
||||||
|
p[2] = c.b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void blend_solid_hspan(int x, int y,
|
||||||
|
unsigned len,
|
||||||
|
const color_type& c,
|
||||||
|
const int8u* covers)
|
||||||
|
{
|
||||||
|
unsigned rowlen = width();
|
||||||
|
int cx = (x - 2 >= 0 ? -2 : -x);
|
||||||
|
int cx_max = (len + 2 <= rowlen ? len + 1 : rowlen - 1);
|
||||||
|
|
||||||
|
int i = (x + cx) % 3;
|
||||||
|
|
||||||
|
int8u rgb[3] = { c.r, c.g, c.b };
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x + cx);
|
||||||
|
|
||||||
|
for (/* */; cx <= cx_max; cx++)
|
||||||
|
{
|
||||||
|
unsigned c_conv = m_lut->convolution(covers, cx, 0, len - 1);
|
||||||
|
unsigned alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
unsigned dst_col = rgb[i], src_col = (*p);
|
||||||
|
*p = (int8u)((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
|
||||||
|
p ++;
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rendering_buffer* m_rbuf;
|
||||||
|
const lcd_distribution_lut* m_lut;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Gamma>
|
||||||
|
class pixfmt_rgb24_lcd_gamma
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef rgba8 color_type;
|
||||||
|
typedef rendering_buffer::row_data row_data;
|
||||||
|
typedef color_type::value_type value_type;
|
||||||
|
typedef color_type::calc_type calc_type;
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
pixfmt_rgb24_lcd_gamma(rendering_buffer& rb, const lcd_distribution_lut& lut, const Gamma& gamma)
|
||||||
|
: m_rbuf(&rb), m_lut(&lut), m_gamma(gamma)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
unsigned width() const {
|
||||||
|
return m_rbuf->width() * 3;
|
||||||
|
}
|
||||||
|
unsigned height() const {
|
||||||
|
return m_rbuf->height();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// This method should never be called when using the scanline_u8.
|
||||||
|
// The use of scanline_p8 should be avoided because if does not works
|
||||||
|
// properly for rendering fonts because single hspan are split in many
|
||||||
|
// hline/hspan elements and pixel whitening happens.
|
||||||
|
void blend_hline(int x, int y, unsigned len,
|
||||||
|
const color_type& c, int8u cover)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void copy_hline(int x, int y, unsigned len, const color_type& c)
|
||||||
|
{
|
||||||
|
int xr = x - (x % 3);
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + xr;
|
||||||
|
for (int ilen = len; ilen > 0; p += 3, ilen -= 3)
|
||||||
|
{
|
||||||
|
p[0] = c.r;
|
||||||
|
p[1] = c.g;
|
||||||
|
p[2] = c.b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
void blend_solid_hspan(int x, int y,
|
||||||
|
unsigned len,
|
||||||
|
const color_type& c,
|
||||||
|
const int8u* covers)
|
||||||
|
{
|
||||||
|
unsigned rowlen = width();
|
||||||
|
int cx = (x - 2 >= 0 ? -2 : -x);
|
||||||
|
int cx_max = (len + 2 <= rowlen ? len + 1 : rowlen - 1);
|
||||||
|
|
||||||
|
int i = (x + cx) % 3;
|
||||||
|
|
||||||
|
int8u rgb[3] = { c.r, c.g, c.b };
|
||||||
|
int8u* p = m_rbuf->row_ptr(y) + (x + cx);
|
||||||
|
|
||||||
|
for (/* */; cx <= cx_max; cx++)
|
||||||
|
{
|
||||||
|
unsigned c_conv = m_lut->convolution(covers, cx, 0, len - 1);
|
||||||
|
unsigned alpha = (c_conv + 1) * (c.a + 1);
|
||||||
|
unsigned dst_col = m_gamma.dir(rgb[i]), src_col = m_gamma.dir(*p);
|
||||||
|
*p = m_gamma.inv((((dst_col - src_col) * alpha) + (src_col << 16)) >> 16);
|
||||||
|
|
||||||
|
p ++;
|
||||||
|
i = (i + 1) % 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
rendering_buffer* m_rbuf;
|
||||||
|
const lcd_distribution_lut* m_lut;
|
||||||
|
const Gamma& m_gamma;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include "font_render_capi.h"
|
||||||
|
|
||||||
|
#include "font_render_lcd.h"
|
||||||
|
|
||||||
|
FontRenderer *FontRendererNew(unsigned int flags, float gamma) {
|
||||||
|
bool hinting = ((flags&FONT_RENDERER_HINTING) != 0);
|
||||||
|
bool kerning = ((flags&FONT_RENDERER_KERNING) != 0);
|
||||||
|
bool subpixel = ((flags&FONT_RENDERER_SUBPIXEL) != 0);
|
||||||
|
font_renderer_lcd *font_renderer = new font_renderer_lcd(hinting, kerning, subpixel, (double) gamma);
|
||||||
|
return (FontRenderer *) font_renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FontRendererLoadFont(FontRenderer *fr_, const char *filename) {
|
||||||
|
font_renderer_lcd *font_renderer = (font_renderer_lcd *) fr_;
|
||||||
|
bool success = font_renderer->load_font(filename);
|
||||||
|
return (success ? 0 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FontRendererDrawText(FontRenderer *fr_, RenColor *pixels, int width, int height, int pitch, const char *text, float text_size, int x, int y, RenColor color) {
|
||||||
|
// FIXME: it works below as long as font_renderer_lcd use a BGRA32 pixel format
|
||||||
|
font_renderer_lcd *font_renderer = (font_renderer_lcd *) fr_;
|
||||||
|
agg::rendering_buffer ren_buf((agg::int8u *) pixels, width, height, -pitch);
|
||||||
|
const agg::rgba8 agg_color(color.r, color.g, color.b);
|
||||||
|
double new_x = font_renderer->render_text(ren_buf, (double) text_size, agg_color, (double) x, (double) y, text);
|
||||||
|
return int(new_x);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
struct FontRenderer_;
|
||||||
|
typedef struct FontRenderer_ FontRenderer;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FONT_RENDERER_HINTING = 1 << 0,
|
||||||
|
FONT_RENDERER_KERNING = 1 << 1,
|
||||||
|
FONT_RENDERER_SUBPIXEL = 1 << 2,
|
||||||
|
|
||||||
|
FONT_RENDERER_DEFAULT = FONT_RENDERER_HINTING | FONT_RENDERER_KERNING | FONT_RENDERER_SUBPIXEL,
|
||||||
|
};
|
||||||
|
|
||||||
|
FontRenderer *FontRendererNew(unsigned int flags, float gamma);
|
||||||
|
int FontRendererLoadFont(FontRenderer *, const char *filename);
|
||||||
|
int FontRendererDrawText(FontRenderer *fr_, RenColor *pixels, int width, int height, int pitch, const char *text, float text_size, int x, int y, RenColor color);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,166 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "agg_basics.h"
|
||||||
|
#include "agg_conv_curve.h"
|
||||||
|
#include "agg_conv_transform.h"
|
||||||
|
#include "agg_gamma_lut.h"
|
||||||
|
#include "agg_font_freetype.h"
|
||||||
|
// #include "agg_pixfmt_rgb.h"
|
||||||
|
#include "agg_pixfmt_rgba.h"
|
||||||
|
// #include "agg_pixfmt_rgb24_lcd.h"
|
||||||
|
#include "agg_pixfmt_bgra32_lcd.h"
|
||||||
|
#include "agg_rasterizer_scanline_aa.h"
|
||||||
|
#include "agg_renderer_primitives.h"
|
||||||
|
#include "agg_renderer_scanline.h"
|
||||||
|
#include "agg_rendering_buffer.h"
|
||||||
|
#include "agg_scanline_u.h"
|
||||||
|
|
||||||
|
// FIXME: the pixel type rgb24 of rgba32 is hard coded below
|
||||||
|
class font_renderer_lcd
|
||||||
|
{
|
||||||
|
typedef agg::pixfmt_bgra32 pixfmt_type;
|
||||||
|
typedef agg::renderer_base<pixfmt_type> base_ren_type;
|
||||||
|
typedef agg::renderer_scanline_aa_solid<base_ren_type> renderer_solid;
|
||||||
|
typedef agg::font_engine_freetype_int32 font_engine_type;
|
||||||
|
typedef agg::font_cache_manager<font_engine_type> font_manager_type;
|
||||||
|
|
||||||
|
font_engine_type m_feng;
|
||||||
|
font_manager_type m_fman;
|
||||||
|
agg::gamma_lut<> m_gamma_lut;
|
||||||
|
|
||||||
|
// Font rendering options.
|
||||||
|
bool m_hinting;
|
||||||
|
bool m_kerning;
|
||||||
|
bool m_grayscale;
|
||||||
|
double m_gamma;
|
||||||
|
|
||||||
|
bool m_font_loaded;
|
||||||
|
|
||||||
|
// Pipeline to process the vectors glyph paths (curves + contour)
|
||||||
|
agg::trans_affine m_mtx;
|
||||||
|
agg::conv_curve<font_manager_type::path_adaptor_type> m_curves;
|
||||||
|
agg::conv_transform<agg::conv_curve<font_manager_type::path_adaptor_type> > m_trans;
|
||||||
|
public:
|
||||||
|
font_renderer_lcd(bool hinting, bool kerning, bool subpixel, double gamma):
|
||||||
|
m_feng(),
|
||||||
|
m_fman(m_feng),
|
||||||
|
m_hinting(hinting),
|
||||||
|
m_kerning(kerning),
|
||||||
|
m_grayscale(!subpixel),
|
||||||
|
m_gamma(gamma),
|
||||||
|
m_font_loaded(false),
|
||||||
|
m_curves(m_fman.path_adaptor()),
|
||||||
|
m_trans(m_curves, m_mtx)
|
||||||
|
{
|
||||||
|
m_gamma_lut.gamma(m_gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load_font(const char *font_filename) {
|
||||||
|
if(m_feng.load_font(font_filename, 0, agg::glyph_ren_outline)) {
|
||||||
|
m_font_loaded = true;
|
||||||
|
}
|
||||||
|
return m_font_loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Rasterizer, class Scanline, class RenSolid>
|
||||||
|
double draw_text(Rasterizer& ras, Scanline& sl,
|
||||||
|
RenSolid& ren_solid, const agg::rgba8 color,
|
||||||
|
const char* text,
|
||||||
|
double x, double y, double height,
|
||||||
|
unsigned subpixel_scale)
|
||||||
|
{
|
||||||
|
const double scale_x = 100;
|
||||||
|
|
||||||
|
m_feng.height(height);
|
||||||
|
m_feng.width(height * scale_x * subpixel_scale);
|
||||||
|
m_feng.hinting(m_hinting);
|
||||||
|
|
||||||
|
const char* p = text;
|
||||||
|
|
||||||
|
// FIXME: check we need to multiply x by scale_x.
|
||||||
|
x *= scale_x * subpixel_scale;
|
||||||
|
double start_x = x;
|
||||||
|
|
||||||
|
while(*p)
|
||||||
|
{
|
||||||
|
if(*p == '\n')
|
||||||
|
{
|
||||||
|
x = start_x;
|
||||||
|
y -= height * 1.25;
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const agg::glyph_cache* glyph = m_fman.glyph(*p);
|
||||||
|
if(glyph)
|
||||||
|
{
|
||||||
|
if(m_kerning)
|
||||||
|
{
|
||||||
|
m_fman.add_kerning(&x, &y);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_fman.init_embedded_adaptors(glyph, 0, 0);
|
||||||
|
if(glyph->data_type == agg::glyph_data_outline)
|
||||||
|
{
|
||||||
|
double ty = m_hinting ? floor(y + 0.5) : y;
|
||||||
|
ras.reset();
|
||||||
|
m_mtx.reset();
|
||||||
|
m_mtx *= agg::trans_affine_scaling(1.0 / scale_x, 1);
|
||||||
|
m_mtx *= agg::trans_affine_translation(start_x + x/scale_x, ty);
|
||||||
|
ras.add_path(m_trans);
|
||||||
|
ren_solid.color(color);
|
||||||
|
agg::render_scanlines(ras, sl, ren_solid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// increment pen position
|
||||||
|
x += glyph->advance_x;
|
||||||
|
y += glyph->advance_y;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
return x / (subpixel_scale * scale_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear(agg::rendering_buffer& ren_buf, const agg::rgba8 color) {
|
||||||
|
agg::pixfmt_bgra32 pf(ren_buf);
|
||||||
|
base_ren_type ren_base(pf);
|
||||||
|
ren_base.clear(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
double render_text(agg::rendering_buffer& ren_buf,
|
||||||
|
const double text_size,
|
||||||
|
const agg::rgba8 text_color,
|
||||||
|
double x, double y,
|
||||||
|
const char *text)
|
||||||
|
{
|
||||||
|
if (!m_font_loaded) {
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
agg::scanline_u8 sl;
|
||||||
|
agg::rasterizer_scanline_aa<> ras;
|
||||||
|
ras.clip_box(0, 0, ren_buf.width()*3, ren_buf.height());
|
||||||
|
|
||||||
|
//--------------------------------------
|
||||||
|
if(m_grayscale)
|
||||||
|
{
|
||||||
|
agg::pixfmt_bgra32 pf(ren_buf);
|
||||||
|
base_ren_type ren_base(pf);
|
||||||
|
renderer_solid ren_solid(ren_base);
|
||||||
|
y = draw_text(ras, sl, ren_solid, text_color, text, x, y, text_size, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Conventional LUT values: (1./3., 2./9., 1./9.)
|
||||||
|
// The values below are fine tuned as in the Elementary Plot library.
|
||||||
|
// The primary weight should be 0.448 but is left adjustable.
|
||||||
|
agg::lcd_distribution_lut lut(0.448, 0.184, 0.092);
|
||||||
|
typedef agg::pixfmt_bgra32_lcd_gamma<agg::gamma_lut<> > pixfmt_lcd_type;
|
||||||
|
pixfmt_lcd_type pf_lcd(ren_buf, lut, m_gamma_lut);
|
||||||
|
agg::renderer_base<pixfmt_lcd_type> ren_base_lcd(pf_lcd);
|
||||||
|
agg::renderer_scanline_aa_solid<agg::renderer_base<pixfmt_lcd_type> > ren_solid_lcd(ren_base_lcd);
|
||||||
|
y = draw_text(ras, sl, ren_solid_lcd, text_color, text, x, y, text_size, 3);
|
||||||
|
}
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
};
|
|
@ -4,6 +4,8 @@ lite_sources = [
|
||||||
'api/renderer_font.c',
|
'api/renderer_font.c',
|
||||||
'api/system.c',
|
'api/system.c',
|
||||||
'renderer.c',
|
'renderer.c',
|
||||||
|
'agg_font_freetype.cpp',
|
||||||
|
'font_render_capi.cpp',
|
||||||
'rencache.c',
|
'rencache.c',
|
||||||
'main.c',
|
'main.c',
|
||||||
]
|
]
|
||||||
|
@ -11,7 +13,7 @@ lite_sources = [
|
||||||
executable('lite',
|
executable('lite',
|
||||||
lite_sources,
|
lite_sources,
|
||||||
include_directories: lite_include,
|
include_directories: lite_include,
|
||||||
dependencies: [lua_dep, sdl_dep, stb_truetype_dep, libm, libdl],
|
dependencies: [lua_dep, sdl_dep, stb_truetype_dep, libagg_dep, freetype_dep, libm, libdl],
|
||||||
install: true,
|
install: true,
|
||||||
gui_app: true,
|
gui_app: true,
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "stb_truetype.h"
|
#include "stb_truetype.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "font_render_capi.h"
|
||||||
|
|
||||||
#define MAX_GLYPHSET 256
|
#define MAX_GLYPHSET 256
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ struct RenFont {
|
||||||
GlyphSet *sets[MAX_GLYPHSET];
|
GlyphSet *sets[MAX_GLYPHSET];
|
||||||
float size;
|
float size;
|
||||||
int height;
|
int height;
|
||||||
|
FontRenderer *renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,6 +195,10 @@ RenFont* ren_load_font(const char *filename, float size) {
|
||||||
g['\t'].x1 = g['\t'].x0;
|
g['\t'].x1 = g['\t'].x0;
|
||||||
g['\n'].x1 = g['\n'].x0;
|
g['\n'].x1 = g['\n'].x0;
|
||||||
|
|
||||||
|
font->renderer = FontRendererNew(FONT_RENDERER_HINTING|FONT_RENDERER_SUBPIXEL, 1.8);
|
||||||
|
// FIXME check for errors
|
||||||
|
FontRendererLoadFont(font->renderer, filename);
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -328,6 +334,11 @@ void ren_draw_image(RenImage *image, RenRect *sub, int x, int y, RenColor color)
|
||||||
|
|
||||||
|
|
||||||
int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) {
|
int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color) {
|
||||||
|
SDL_Surface *surf = SDL_GetWindowSurface(window);
|
||||||
|
// FIXME: pixels are arranged in bgra order while AGG::fontrender use rgb
|
||||||
|
RenColor *pixels = (RenColor*) surf->pixels;
|
||||||
|
return FontRendererDrawText(font->renderer, pixels, surf->w, surf->h, surf->pitch, text, font->height, x, y, color);
|
||||||
|
#if 0
|
||||||
RenRect rect;
|
RenRect rect;
|
||||||
const char *p = text;
|
const char *p = text;
|
||||||
unsigned codepoint;
|
unsigned codepoint;
|
||||||
|
@ -343,4 +354,5 @@ int ren_draw_text(RenFont *font, const char *text, int x, int y, RenColor color)
|
||||||
x += g->xadvance;
|
x += g->xadvance;
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue