From 10f9d16b174742f68e7cb20ce975895d44090d26 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 25 Mar 2013 17:46:37 +0100 Subject: [PATCH] Antigrain-lite test --- Makefile | 12 +- agg_test.cpp | 141 ++ libagl/Makefile | 22 + libagl/agg.cpp | 892 ++++++++++++ libagl/include/agg.h | 1270 +++++++++++++++++ libfreetype/Makefile | 46 - .../include/freetype/config/ftmodule.h | 20 - .../include/freetype/config/ftoption.h | 805 ----------- main.c | 3 + 9 files changed, 2337 insertions(+), 874 deletions(-) create mode 100644 agg_test.cpp create mode 100644 libagl/Makefile create mode 100644 libagl/agg.cpp create mode 100644 libagl/include/agg.h delete mode 100644 libfreetype/Makefile delete mode 100644 libfreetype/include/freetype/config/ftmodule.h delete mode 100644 libfreetype/include/freetype/config/ftoption.h diff --git a/Makefile b/Makefile index 720c3cf..ee0e806 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,12 @@ MISPDIR=. include $(MISPDIR)/common.mak -OBJECTS=crt0.o isr.o luainit.o main.o -OURLIBS=m mm yaffs2 glue lua lfs freetype +OBJECTS=crt0.o isr.o luainit.o agg_test.o main.o +OURLIBS=m mm yaffs2 glue lua lfs agl -CFLAGS+=-I$(MISPDIR)/libm/include -I$(MISPDIR)/libmm/include -I$(MISPDIR)/libglue/include -I$(LUADIR)/src -I$(MISPDIR)/liblfs/include +INCFLAGS=-I$(MISPDIR)/libm/include -I$(MISPDIR)/libmm/include -I$(MISPDIR)/libglue/include -I$(LUADIR)/src -I$(MISPDIR)/liblfs/include -I$(MISPDIR)/libagl/include +CFLAGS+=$(INCFLAGS) +CXXFLAGS+=$(INCFLAGS) all: misp.bin @@ -25,9 +27,13 @@ misp.elf: linker.ld $(OBJECTS) libs --start-group -lbase -lcompiler-rt $(addprefix -l,$(OURLIBS)) --end-group chmod -x $@ +%.o: %.cpp + $(compilexx-dep) + %.o: %.c $(compile-dep) + libs: set -e; \ for lib in $(OURLIBS); do \ diff --git a/agg_test.cpp b/agg_test.cpp new file mode 100644 index 0000000..4491eb4 --- /dev/null +++ b/agg_test.cpp @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include "agg.h" + +enum +{ + width = 640, + height = 480 +}; + + +double random(double min, double max) +{ + int r = (rand() << 15) | rand(); + return ((r & 0xFFFFFFF) / double(0xFFFFFFF + 1)) * (max - min) + min; +} + + +void draw_ellipse(agg::rasterizer& ras, + double x, double y, + double rx, double ry) +{ + int i; + ras.move_to_d(x + rx, y); + + // Here we have a fixed number of approximation steps, namely 360 + // while in reality it's supposed to be smarter. + for(i = 1; i < 360; i++) + { + double a = double(i) * 3.1415926 / 180.0; + ras.line_to_d(x + cos(a) * rx, y + sin(a) * ry); + } +} + + +void draw_line(agg::rasterizer& ras, + double x1, double y1, + double x2, double y2, + double width) +{ + + double dx = x2 - x1; + double dy = y2 - y1; + double d = sqrt(dx*dx + dy*dy); + + dx = width * (y2 - y1) / d; + dy = width * (x2 - x1) / d; + + ras.move_to_d(x1 - dx, y1 + dy); + ras.line_to_d(x2 - dx, y2 + dy); + ras.line_to_d(x2 + dx, y2 - dy); + ras.line_to_d(x1 + dx, y1 - dy); +} + +static void start_fb(unsigned char *addr) +{ + fb_base_write((unsigned int)addr); + fb_enable_write(1); +} + +extern "C" void agg_test(void); +void agg_test(void) +{ + // Allocate the framebuffer + unsigned char* buf = new unsigned char[width * height * 4]; + + start_fb(buf); + + // Create the rendering buffer + agg::rendering_buffer rbuf(buf, width, height, width * 4); + + // Create the renderer and the rasterizer + agg::renderer ren(rbuf); + agg::rasterizer ras; + + // Setup the rasterizer + ras.gamma(1.3); + ras.filling_rule(agg::fill_even_odd); + + ren.clear(agg::rgba8(255, 255, 255)); + + int i; + + // Draw random polygons + for(i = 0; i < 10; i++) + { + int n = rand() % 6 + 3; + + // Make the polygon. One can call move_to() more than once. + // In this case the rasterizer behaves like Win32 API PolyPolygon(). + ras.move_to_d(random(-30, rbuf.width() + 30), + random(-30, rbuf.height() + 30)); + + int j; + for(j = 1; j < n; j++) + { + ras.line_to_d(random(-30, rbuf.width() + 30), + random(-30, rbuf.height() + 30)); + } + + // Render + ras.render(ren, agg::rgba8(rand() & 0xFF, + rand() & 0xFF, + rand() & 0xFF, + rand() & 0xFF)); + } + + // Draw random ellipses + for(i = 0; i < 50; i++) + { + draw_ellipse(ras, + random(-30, rbuf.width() + 30), + random(-30, rbuf.height() + 30), + random(3, 50), + random(3, 50)); + ras.render(ren, agg::rgba8(rand() & 0x7F, + rand() & 0x7F, + rand() & 0x7F, + (rand() & 0x7F) + 100)); + } + + // Draw random straight lines + for(i = 0; i < 20; i++) + { + draw_line(ras, + random(-30, rbuf.width() + 30), + random(-30, rbuf.height() + 30), + random(-30, rbuf.width() + 30), + random(-30, rbuf.height() + 30), + random(0.1, 10)); + + ras.render(ren, agg::rgba8(rand() & 0x7F, + rand() & 0x7F, + rand() & 0x7F)); + } + + delete [] buf; +} + diff --git a/libagl/Makefile b/libagl/Makefile new file mode 100644 index 0000000..671ea32 --- /dev/null +++ b/libagl/Makefile @@ -0,0 +1,22 @@ +MISPDIR=.. +include $(MISPDIR)/common.mak + +CXXFLAGS+=-I$(MISPDIR)/libagl/include -I$(MISPDIR)/libm/include +OBJECTS=agg.o + +all: libagl.a + +# pull in dependency info for *existing* .o files +-include $(OBJECTS:.o=.d) + +libagl.a: $(OBJECTS) + $(AR) clr libagl.a $(OBJECTS) + $(RANLIB) libagl.a + +%.o: %.cpp + $(compilexx-dep) + +.PHONY: clean + +clean: + rm -f $(OBJECTS) $(OBJECTS:.o=.d) libagl.a .*~ *~ diff --git a/libagl/agg.cpp b/libagl/agg.cpp new file mode 100644 index 0000000..8784272 --- /dev/null +++ b/libagl/agg.cpp @@ -0,0 +1,892 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.1 Lite +// Copyright (C) 2002-2003 Maxim Shemanarev (McSeem) +// +// 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. +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Class outline - implementation. +// +// Initially the rendering algorithm was designed by David Turner and the +// other authors of the FreeType library - see the above notice. I nearly +// created a similar renderer, but still I was far from David's work. +// I completely redesigned the original code and adapted it for Anti-Grain +// ideas. Two functions - render_line and render_scanline are the core of +// the algorithm - they calculate the exact coverage of each pixel cell +// of the polygon. I left these functions almost as is, because there's +// no way to improve the perfection - hats off to David and his group! +// +// All other code is very different from the original. +// +//---------------------------------------------------------------------------- + + +#include +#include "agg.h" + + +namespace agg +{ + + + //======================================================================== + + //------------------------------------------------------------------------ + rendering_buffer::~rendering_buffer() + { + delete [] m_rows; + } + + + //------------------------------------------------------------------------ + rendering_buffer::rendering_buffer(unsigned char* buf, + unsigned width, + unsigned height, + int stride) : + m_buf(0), + m_rows(0), + m_width(0), + m_height(0), + m_stride(0), + m_max_height(0) + { + attach(buf, width, height, stride); + } + + + //------------------------------------------------------------------------ + void rendering_buffer::attach(unsigned char* buf, + unsigned width, + unsigned height, + int stride) + { + m_buf = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(height > m_max_height) + { + delete [] m_rows; + m_rows = new unsigned char* [m_max_height = height]; + } + + unsigned char* row_ptr = m_buf; + + if(stride < 0) + { + row_ptr = m_buf - int(height - 1) * stride; + } + + unsigned char** rows = m_rows; + + while(height--) + { + *rows++ = row_ptr; + row_ptr += stride; + } + } + + + //======================================================================== + + //------------------------------------------------------------------------ + scanline::~scanline() + { + delete [] m_counts; + delete [] m_start_ptrs; + delete [] m_covers; + } + + + //------------------------------------------------------------------------ + scanline::scanline() + : m_min_x(0), + m_max_len(0), + m_dx(0), + m_dy(0), + m_last_x(0x7FFF), + m_last_y(0x7FFF), + m_covers(0), + m_start_ptrs(0), + m_counts(0), + m_num_spans(0), + m_cur_start_ptr(0), + m_cur_count(0) + { + } + + + //------------------------------------------------------------------------ + void scanline::reset(int min_x, int max_x, int dx, int dy) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_max_len) + { + delete [] m_counts; + delete [] m_start_ptrs; + delete [] m_covers; + m_covers = new unsigned char [max_len]; + m_start_ptrs = new unsigned char* [max_len]; + m_counts = new int16u[max_len]; + m_max_len = max_len; + } + m_dx = dx; + m_dy = dy; + m_last_x = 0x7FFF; + m_last_y = 0x7FFF; + m_min_x = min_x; + m_cur_count = m_counts; + m_cur_start_ptr = m_start_ptrs; + m_num_spans = 0; + } + + + //------------------------------------------------------------------------ + void scanline::add_span(int x, int y, unsigned num, unsigned cover) + { + x -= m_min_x; + + memset(m_covers + x, cover, num); + if(x == m_last_x+1) + { + (*m_cur_count) += (int16u)num; + } + else + { + *++m_cur_count = (int16u)num; + *++m_cur_start_ptr = m_covers + x; + m_num_spans++; + } + m_last_x = x + num - 1; + m_last_y = y; + } + + + + //======================================================================== + + //------------------------------------------------------------------------ + const int8u rasterizer::s_default_gamma[] = + { + 0, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, + 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 15, 16, 16, 17, 18, 18, + 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25, 25, 26, 27, 27, 28, + 29, 29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 36, 37, 37, 38, + 39, 39, 40, 41, 41, 42, 43, 43, 44, 45, 45, 46, 47, 47, 48, 49, + 49, 50, 51, 51, 52, 53, 53, 54, 55, 55, 56, 57, 57, 58, 59, 60, + 60, 61, 62, 62, 63, 64, 65, 65, 66, 67, 68, 68, 69, 70, 71, 71, + 72, 73, 74, 74, 75, 76, 77, 78, 78, 79, 80, 81, 82, 83, 83, 84, + 85, 86, 87, 88, 89, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100,101,101,102,103,104,105,106,107,108,109,110,111,112,114,115, + 116,117,118,119,120,121,122,123,124,126,127,128,129,130,131,132, + 134,135,136,137,139,140,141,142,144,145,146,147,149,150,151,153, + 154,155,157,158,159,161,162,164,165,166,168,169,171,172,174,175, + 177,178,180,181,183,184,186,188,189,191,192,194,195,197,199,200, + 202,204,205,207,209,210,212,214,215,217,219,220,222,224,225,227, + 229,230,232,234,236,237,239,241,242,244,246,248,249,251,253,255 + }; + + + + + + //======================================================================== + enum + { + not_closed = 1, + sort_required = 2 + }; + + //------------------------------------------------------------------------ + inline void cell::set_cover(int c, int a) + { + cover = c; + area = a; + } + + //------------------------------------------------------------------------ + inline void cell::add_cover(int c, int a) + { + cover += c; + area += a; + } + + //------------------------------------------------------------------------ + inline void cell::set_coord(int cx, int cy) + { + x = int16(cx); + y = int16(cy); + packed_coord = (cy << 16) + cx; + } + + //------------------------------------------------------------------------ + inline void cell::set(int cx, int cy, int c, int a) + { + x = int16(cx); + y = int16(cy); + packed_coord = (cy << 16) + cx; + cover = c; + area = a; + } + + //------------------------------------------------------------------------ + outline::~outline() + { + delete [] m_sorted_cells; + if(m_num_blocks) + { + cell** ptr = m_cells + m_num_blocks - 1; + while(m_num_blocks--) + { + delete [] *ptr; + ptr--; + } + delete [] m_cells; + } + } + + + //------------------------------------------------------------------------ + outline::outline() : + m_num_blocks(0), + m_max_blocks(0), + m_cur_block(0), + m_num_cells(0), + m_cells(0), + m_cur_cell_ptr(0), + m_sorted_cells(0), + m_sorted_size(0), + m_cur_x(0), + m_cur_y(0), + m_close_x(0), + m_close_y(0), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF), + m_flags(sort_required) + { + m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); + } + + + //------------------------------------------------------------------------ + void outline::reset() + { + m_num_cells = 0; + m_cur_block = 0; + m_cur_cell.set(0x7FFF, 0x7FFF, 0, 0); + m_flags |= sort_required; + m_flags &= ~not_closed; + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + } + + + + //------------------------------------------------------------------------ + void outline::allocate_block() + { + if(m_cur_block >= m_num_blocks) + { + if(m_num_blocks >= m_max_blocks) + { + cell** new_cells = new cell* [m_max_blocks + cell_block_pool]; + if(m_cells) + { + memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell*)); + delete [] m_cells; + } + m_cells = new_cells; + m_max_blocks += cell_block_pool; + } + m_cells[m_num_blocks++] = new cell [unsigned(cell_block_size)]; + } + m_cur_cell_ptr = m_cells[m_cur_block++]; + } + + + //------------------------------------------------------------------------ + inline void outline::add_cur_cell() + { + if(m_cur_cell.area | m_cur_cell.cover) + { + if((m_num_cells & cell_block_mask) == 0) + { + if(m_num_blocks >= cell_block_limit) return; + allocate_block(); + } + *m_cur_cell_ptr++ = m_cur_cell; + m_num_cells++; + } + } + + + + //------------------------------------------------------------------------ + inline void outline::set_cur_cell(int x, int y) + { + if(m_cur_cell.packed_coord != (y << 16) + x) + { + add_cur_cell(); + m_cur_cell.set(x, y, 0, 0); + } + } + + + + //------------------------------------------------------------------------ + inline void outline::render_scanline(int ey, int x1, int y1, int x2, int y2) + { + int ex1 = x1 >> poly_base_shift; + int ex2 = x2 >> poly_base_shift; + int fx1 = x1 & poly_base_mask; + int fx2 = x2 & poly_base_mask; + + int delta, p, first, dx; + int incr, lift, mod, rem; + + //trivial case. Happens often + if(y1 == y2) + { + set_cur_cell(ex2, ey); + return; + } + + //everything is located in a single cell. That is easy! + if(ex1 == ex2) + { + delta = y2 - y1; + m_cur_cell.add_cover(delta, (fx1 + fx2) * delta); + return; + } + + //ok, we'll have to render a run of adjacent cells on the same + //scanline... + p = (poly_base_size - fx1) * (y2 - y1); + first = poly_base_size; + incr = 1; + + dx = x2 - x1; + + if(dx < 0) + { + p = fx1 * (y2 - y1); + first = 0; + incr = -1; + dx = -dx; + } + + delta = p / dx; + mod = p % dx; + + if(mod < 0) + { + delta--; + mod += dx; + } + + m_cur_cell.add_cover(delta, (fx1 + first) * delta); + + ex1 += incr; + set_cur_cell(ex1, ey); + y1 += delta; + + if(ex1 != ex2) + { + p = poly_base_size * (y2 - y1 + delta); + lift = p / dx; + rem = p % dx; + + if (rem < 0) + { + lift--; + rem += dx; + } + + mod -= dx; + + while (ex1 != ex2) + { + delta = lift; + mod += rem; + if(mod >= 0) + { + mod -= dx; + delta++; + } + + m_cur_cell.add_cover(delta, (poly_base_size) * delta); + y1 += delta; + ex1 += incr; + set_cur_cell(ex1, ey); + } + } + delta = y2 - y1; + m_cur_cell.add_cover(delta, (fx2 + poly_base_size - first) * delta); + } + + + + + + + //------------------------------------------------------------------------ + void outline::render_line(int x1, int y1, int x2, int y2) + { + int ey1 = y1 >> poly_base_shift; + int ey2 = y2 >> poly_base_shift; + int fy1 = y1 & poly_base_mask; + int fy2 = y2 & poly_base_mask; + + int dx, dy, x_from, x_to; + int p, rem, mod, lift, delta, first, incr; + + if(ey1 < m_min_y) m_min_y = ey1; + if(ey1+1 > m_max_y) m_max_y = ey1+1; + if(ey2 < m_min_y) m_min_y = ey2; + if(ey2+1 > m_max_y) m_max_y = ey2+1; + + dx = x2 - x1; + dy = y2 - y1; + + //everything is on a single scanline + if(ey1 == ey2) + { + render_scanline(ey1, x1, fy1, x2, fy2); + return; + } + + //Vertical line - we have to calculate start and end cells, + //and then - the common values of the area and coverage for + //all cells of the line. We know exactly there's only one + //cell, so, we don't have to call render_scanline(). + incr = 1; + if(dx == 0) + { + int ex = x1 >> poly_base_shift; + int two_fx = (x1 - (ex << poly_base_shift)) << 1; + int area; + + first = poly_base_size; + if(dy < 0) + { + first = 0; + incr = -1; + } + + x_from = x1; + + //render_scanline(ey1, x_from, fy1, x_from, first); + delta = first - fy1; + m_cur_cell.add_cover(delta, two_fx * delta); + + ey1 += incr; + set_cur_cell(ex, ey1); + + delta = first + first - poly_base_size; + area = two_fx * delta; + while(ey1 != ey2) + { + //render_scanline(ey1, x_from, poly_base_size - first, x_from, first); + m_cur_cell.set_cover(delta, area); + ey1 += incr; + set_cur_cell(ex, ey1); + } + //render_scanline(ey1, x_from, poly_base_size - first, x_from, fy2); + delta = fy2 - poly_base_size + first; + m_cur_cell.add_cover(delta, two_fx * delta); + return; + } + + //ok, we have to render several scanlines + p = (poly_base_size - fy1) * dx; + first = poly_base_size; + + if(dy < 0) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = p / dy; + mod = p % dy; + + if(mod < 0) + { + delta--; + mod += dy; + } + + x_from = x1 + delta; + render_scanline(ey1, x1, fy1, x_from, first); + + ey1 += incr; + set_cur_cell(x_from >> poly_base_shift, ey1); + + if(ey1 != ey2) + { + p = poly_base_size * dx; + lift = p / dy; + rem = p % dy; + + if(rem < 0) + { + lift--; + rem += dy; + } + mod -= dy; + + while(ey1 != ey2) + { + delta = lift; + mod += rem; + if (mod >= 0) + { + mod -= dy; + delta++; + } + + x_to = x_from + delta; + render_scanline(ey1, x_from, poly_base_size - first, x_to, first); + x_from = x_to; + + ey1 += incr; + set_cur_cell(x_from >> poly_base_shift, ey1); + } + } + render_scanline(ey1, x_from, poly_base_size - first, x2, fy2); + } + + + //------------------------------------------------------------------------ + void outline::move_to(int x, int y) + { + if((m_flags & sort_required) == 0) reset(); + if(m_flags & not_closed) line_to(m_close_x, m_close_y); + set_cur_cell(x >> poly_base_shift, y >> poly_base_shift); + m_close_x = m_cur_x = x; + m_close_y = m_cur_y = y; + } + + + + //------------------------------------------------------------------------ + void outline::line_to(int x, int y) + { + if((m_flags & sort_required) && ((m_cur_x ^ x) | (m_cur_y ^ y))) + { + int c; + + c = m_cur_x >> poly_base_shift; + if(c < m_min_x) m_min_x = c; + ++c; + if(c > m_max_x) m_max_x = c; + + c = x >> poly_base_shift; + if(c < m_min_x) m_min_x = c; + ++c; + if(c > m_max_x) m_max_x = c; + + render_line(m_cur_x, m_cur_y, x, y); + m_cur_x = x; + m_cur_y = y; + m_flags |= not_closed; + } + } + + + enum + { + qsort_threshold = 9 + }; + + + //------------------------------------------------------------------------ + template static inline void swap_cells(T* a, T* b) + { + T temp = *a; + *a = *b; + *b = temp; + } + + //------------------------------------------------------------------------ + template static inline bool less_than(T* a, T* b) + { + return (*a)->packed_coord < (*b)->packed_coord; + } + + + + //------------------------------------------------------------------------ + void outline::qsort_cells(cell** start, unsigned num) + { + cell** stack[80]; + cell*** top; + cell** limit; + cell** base; + + limit = start + num; + base = start; + top = stack; + + for (;;) + { + int len = int(limit - base); + + cell** i; + cell** j; + cell** pivot; + + if(len > qsort_threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + swap_cells(base, pivot); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + if(less_than(j, i)) + { + swap_cells(i, j); + } + + if(less_than(base, i)) + { + swap_cells(base, i); + } + + if(less_than(j, base)) + { + swap_cells(base, j); + } + + for(;;) + { + do i++; while( less_than(i, base) ); + do j--; while( less_than(base, j) ); + + if ( i > j ) + { + break; + } + + swap_cells(i, j); + } + + swap_cells(base, j); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; less_than(j + 1, j); j--) + { + swap_cells(j + 1, j); + if (j == base) + { + break; + } + } + } + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + } + + + + + + //------------------------------------------------------------------------ + void outline::sort_cells() + { + if(m_num_cells == 0) return; + if(m_num_cells > m_sorted_size) + { + delete [] m_sorted_cells; + m_sorted_size = m_num_cells; + m_sorted_cells = new cell* [m_num_cells + 1]; + } + + cell** sorted_ptr = m_sorted_cells; + cell** block_ptr = m_cells; + cell* cell_ptr; + + unsigned nb = m_num_cells >> cell_block_shift; + unsigned i; + + while(nb--) + { + cell_ptr = *block_ptr++; + i = cell_block_size; + while(i--) + { + *sorted_ptr++ = cell_ptr++; + } + } + + cell_ptr = *block_ptr++; + i = m_num_cells & cell_block_mask; + while(i--) + { + *sorted_ptr++ = cell_ptr++; + } + m_sorted_cells[m_num_cells] = 0; + qsort_cells(m_sorted_cells, m_num_cells); + } + + + + + //------------------------------------------------------------------------ + const cell* const* outline::cells() + { + if(m_flags & not_closed) + { + line_to(m_close_x, m_close_y); + m_flags &= ~not_closed; + } + + //Perform sort only the first time. + if(m_flags & sort_required) + { + add_cur_cell(); + if(m_num_cells == 0) return 0; + sort_cells(); + m_flags &= ~sort_required; + } + return m_sorted_cells; + } + + + + //------------------------------------------------------------------------ + void rasterizer::gamma(double g) + { + unsigned i; + for(i = 0; i < 256; i++) + { + m_gamma[i] = (unsigned char)(pow(double(i) / 255.0, g) * 255.0); + } + } + + + //------------------------------------------------------------------------ + void rasterizer::gamma(const int8u* g) + { + memcpy(m_gamma, g, sizeof(m_gamma)); + } + + + //------------------------------------------------------------------------ + bool rasterizer::hit_test(int tx, int ty) + { + const cell* const* cells = m_outline.cells(); + if(m_outline.num_cells() == 0) return false; + + int x, y; + int cover; + int alpha; + int area; + + cover = 0; + const cell* cur_cell = *cells++; + for(;;) + { + const cell* start_cell = cur_cell; + + int coord = cur_cell->packed_coord; + x = cur_cell->x; + y = cur_cell->y; + + if(y > ty) return false; + + area = start_cell->area; + cover += start_cell->cover; + + while((cur_cell = *cells++) != 0) + { + if(cur_cell->packed_coord != coord) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area); + if(alpha) + { + if(tx == x && ty == y) return true; + } + x++; + } + + if(!cur_cell) break; + + if(cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_base_shift + 1)); + if(alpha) + { + if(ty == y && tx >= x && tx <= cur_cell->x) return true; + } + } + } + return false; + } + + + +} + + + + + diff --git a/libagl/include/agg.h b/libagl/include/agg.h new file mode 100644 index 0000000..f1dff58 --- /dev/null +++ b/libagl/include/agg.h @@ -0,0 +1,1270 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.1 Lite +// Copyright (C) 2002-2003 Maxim Shemanarev (McSeem) +// +// 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. +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_INCLUDED +#define AGG_INCLUDED + +#include + +namespace agg +{ + //------------------------------------------------------------------------ + typedef signed char int8; + typedef unsigned char int8u; + typedef signed short int16; + typedef unsigned short int16u; + typedef signed int int32; + typedef unsigned int int32u; + + + + //======================================================================== + struct rgba8 + { + enum order { rgb, bgr }; + + int8u r; + int8u g; + int8u b; + int8u a; + + //-------------------------------------------------------------------- + rgba8() {} + + //-------------------------------------------------------------------- + rgba8(unsigned r_, unsigned g_, unsigned b_, unsigned a_=255) : + r(int8u(r_)), g(int8u(g_)), b(int8u(b_)), a(int8u(a_)) {} + + //-------------------------------------------------------------------- + rgba8(unsigned packed, order o) : + r((o == rgb) ? ((packed >> 16) & 0xFF) : (packed & 0xFF)), + g((packed >> 8) & 0xFF), + b((o == rgb) ? (packed & 0xFF) : ((packed >> 16) & 0xFF)), + a(255) {} + + //-------------------------------------------------------------------- + void opacity(double a_) + { + if(a_ < 0.0) a_ = 0.0; + if(a_ > 1.0) a_ = 1.0; + a = int8u(a_ * 255.0); + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / 255.0; + } + + //-------------------------------------------------------------------- + rgba8 gradient(rgba8 c, double k) const + { + rgba8 ret; + int ik = int(k * 256); + ret.r = int8u(int(r) + (((int(c.r) - int(r)) * ik) >> 8)); + ret.g = int8u(int(g) + (((int(c.g) - int(g)) * ik) >> 8)); + ret.b = int8u(int(b) + (((int(c.b) - int(b)) * ik) >> 8)); + ret.a = int8u(int(a) + (((int(c.a) - int(a)) * ik) >> 8)); + return ret; + } + + rgba8 pre() const + { + return rgba8((r*a) >> 8, (g*a) >> 8, (b*a) >> 8, a); + } + }; + + + //======================================================================== + // Rendering buffer wrapper. This class does not know anything about + // memory organizations, all it does it keeps an array of pointers + // to each pixel row. The general rules of rendering are as follows. + // + // 1. Allocate or create somehow a rendering buffer itself. Since + // the library does not depend on any particular platform or + // architecture it was decided that it's your responsibility + // to create and destroy rendering buffers properly. You can use + // any available mechanism to create it - you can use a system API + // function, simple memory allocation, or even statically defined array. + // You also should know the memory organization (or possible variants) + // in your system. For example, there's an R,G,B or B,G,R organizations + // with one byte per component (three byter per pixel) is used very often. + // So, if you intend to use class render_bgr24, for example, you should + // allocate at least width*height*3 bytes of memory. + // + // 2. Create a rendering_buffer object and then call method attach(). It requires + // a pointer to the buffer itself, width and height of the buffer in + // pixels, and the length of the row in bytes. All these values must + // properly correspond to the memory organization. The argument stride + // is used because in reality the row length in bytes does not obligatory + // correspond with the width of the image in pixels, i.e. it cannot be + // simply calculated as width_in_pixels * bytes_per_pixel. For example, + // it must be aligned to 4 bytes in Windows bitmaps. Besides, the value + // of stride can be negative - it depends on the order of displaying + // the rendering buffer - from top to bottom or from bottom to top. + // In other words, if stride > 0 the pointers to each row will start + // from the beginning of the buffer and increase. If it < 0, the pointers + // start from the end of the buffer and decrease. It gives you an + // additional degree of freedom. + // Method attach() can be called more than once. The execution time of it + // is very little, still it allocates memory of heigh * sizeof(char*) bytes + // and has a loop while(height--) {...}, so it's unreasonable to call it + // every time before drawing any single pixel :-) + // + // 3. Create an object (or a number of objects) of a rendering class, such as + // renderer_bgr24_solid, renderer_bgr24_image and so on. These classes + // require a pointer to the renderer_buffer object, but they do not perform + // any considerable operations except storing this pointer. So, rendering + // objects can be created on demand almost any time. These objects know + // about concrete memory organization (this knowledge is hardcoded), so + // actually, the memory you allocated or created in clause 1 should + // actually be in correspondence to the needs of the rendering class. + // + // 4. Rener your image using rendering classes, for example, rasterizer + // + // 5. Display the result, or store it, or whatever. It's also your + // responsibility and depends on the platform. + //------------------------------------------------------------------------ + class rendering_buffer + { + public: + ~rendering_buffer(); + + //-----------------------------------------Initialization + rendering_buffer(unsigned char* buf, + unsigned width, + unsigned height, + int stride); + + //-----------------------------------------Initialization + void attach(unsigned char* buf, + unsigned width, + unsigned height, + int stride); + + //-----------------------------------------Acessors + const unsigned char* buf() const { return m_buf; } + unsigned width() const { return m_width; } + unsigned height() const { return m_height; } + int stride() const { return m_stride; } + + bool inbox(int x, int y) const + { + return x >= 0 && y >= 0 && x < int(m_width) && y < int(m_height); + } + + unsigned abs_stride() const + { + return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); + } + + unsigned char* row(unsigned y) { return m_rows[y]; } + const unsigned char* row(unsigned y) const { return m_rows[y]; } + + private: + rendering_buffer(const rendering_buffer&); + const rendering_buffer& operator = (const rendering_buffer&); + + private: + unsigned char* m_buf; // Pointer to renrdering buffer + unsigned char** m_rows; // Pointers to each row of the buffer + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + int m_stride; // Number of bytes per row. Can be < 0 + unsigned m_max_height; // Maximal current height + }; + + + + //======================================================================== + // + // This class is used to transfer data from class outline (or a similar one) + // to the rendering buffer. It's organized very simple. The class stores + // information of horizontal spans to render it into a pixel-map buffer. + // Each span has initial X, length, and an array of bytes that determine the + // alpha-values for each pixel. So, the restriction of using this class is 256 + // levels of Anti-Aliasing, which is quite enough for any practical purpose. + // Before using this class you should know the minimal and maximal pixel + // coordinates of your scanline. The protocol of using is: + // 1. reset(min_x, max_x) + // 2. add_cell() / add_span() - accumulate scanline. You pass Y-coordinate + // into these functions in order to make scanline know the last Y. Before + // calling add_cell() / add_span() you should check with method is_ready(y) + // if the last Y has changed. It also checks if the scanline is not empty. + // When forming one scanline the next X coordinate must be always greater + // than the last stored one, i.e. it works only with ordered coordinates. + // 3. If the current scanline is_ready() you should render it and then call + // reset_spans() before adding new cells/spans. + // + // 4. Rendering: + // + // Scanline provides an iterator class that allows you to extract + // the spans and the cover values for each pixel. Be aware that clipping + // has not been done yet, so you should perform it yourself. + // Use scanline::iterator to render spans: + //------------------------------------------------------------------------- + // + // int base_x = sl.base_x(); // base X. Should be added to the span's X + // // "sl" is a const reference to the + // // scanline passed in. + // + // int y = sl.y(); // Y-coordinate of the scanline + // + // ************************************ + // ...Perform vertical clipping here... + // ************************************ + // + // scanline::iterator span(sl); + // + // unsigned char* row = m_rbuf->row(y); // The the address of the beginning + // // of the current row + // + // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that + // // num_spans is always greater than 0. + // + // do + // { + // int x = span.next() + base_x; // The beginning X of the span + // + // const int8u covers* = span.covers(); // The array of the cover values + // + // int num_pix = span.num_pix(); // Number of pixels of the span. + // // Always greater than 0, still we + // // shoud use "int" instead of + // // "unsigned" because it's more + // // convenient for clipping + // + // ************************************** + // ...Perform horizontal clipping here... + // ...you have x, covers, and pix_count.. + // ************************************** + // + // unsigned char* dst = row + x; // Calculate the start address of the row. + // // In this case we assume a simple + // // grayscale image 1-byte per pixel. + // do + // { + // *dst++ = *covers++; // Hypotetical rendering. + // } + // while(--num_pix); + // } + // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe + //------------------------------------------------------------------------ + // + // The question is: why should we accumulate the whole scanline when we + // could render just separate spans when they're ready? + // That's because using the scaline is in general faster. When is consists + // of more than one span the conditions for the processor cash system + // are better, because switching between two different areas of memory + // (that can be large ones) occures less frequently. + //------------------------------------------------------------------------ + class scanline + { + public: + enum { aa_shift = 8 }; + + class iterator + { + public: + iterator(const scanline& sl) : + m_covers(sl.m_covers), + m_cur_count(sl.m_counts), + m_cur_start_ptr(sl.m_start_ptrs) + { + } + + int next() + { + ++m_cur_count; + ++m_cur_start_ptr; + return int(*m_cur_start_ptr - m_covers); + } + + int num_pix() const { return int(*m_cur_count); } + const int8u* covers() const { return *m_cur_start_ptr; } + + private: + const int8u* m_covers; + const int16u* m_cur_count; + const int8u* const* m_cur_start_ptr; + }; + + friend class iterator; + + ~scanline(); + scanline(); + + void reset(int min_x, int max_x, int dx=0, int dy=0); + + void reset_spans(); + void add_cell(int x, int y, unsigned cover); + void add_span(int x, int y, unsigned len, unsigned cover); + int is_ready(int y) const; + int base_x() const { return m_min_x + m_dx; } + int y() const { return m_last_y + m_dy; } + unsigned num_spans() const { return m_num_spans; } + + private: + scanline(const scanline&); + const scanline& operator = (const scanline&); + + private: + int m_min_x; + unsigned m_max_len; + int m_dx; + int m_dy; + int m_last_x; + int m_last_y; + int8u* m_covers; + int8u** m_start_ptrs; + int16u* m_counts; + unsigned m_num_spans; + int8u** m_cur_start_ptr; + int16u* m_cur_count; + }; + + + //------------------------------------------------------------------------ + inline void scanline::reset_spans() + { + m_last_x = 0x7FFF; + m_last_y = 0x7FFF; + m_cur_count = m_counts; + m_cur_start_ptr = m_start_ptrs; + m_num_spans = 0; + } + + + //------------------------------------------------------------------------ + inline void scanline::add_cell(int x, int y, unsigned cover) + { + x -= m_min_x; + m_covers[x] = (unsigned char)cover; + if(x == m_last_x+1) + { + (*m_cur_count)++; + } + else + { + *++m_cur_count = 1; + *++m_cur_start_ptr = m_covers + x; + m_num_spans++; + } + m_last_x = x; + m_last_y = y; + } + + + //------------------------------------------------------------------------ + inline int scanline::is_ready(int y) const + { + return m_num_spans && (y ^ m_last_y); + } + + + + + //======================================================================== + // This class template is used basically for rendering scanlines. + // The 'Span' argument is one of the span renderers, such as span_rgb24 + // and others. + // + // Usage: + // + // // Creation + // agg::rendering_buffer rbuf(ptr, w, h, stride); + // agg::renderer ren(rbuf); + // agg::rasterizer ras; + // + // // Clear the frame buffer + // ren.clear(agg::rgba8(0,0,0)); + // + // // Making polygon + // // ras.move_to(. . .); + // // ras.line_to(. . .); + // // . . . + // + // // Rendering + // ras.render(ren, agg::rgba8(200, 100, 80)); + // + //------------------------------------------------------------------------ + template class renderer + { + public: + //-------------------------------------------------------------------- + renderer(rendering_buffer& rbuf) : m_rbuf(&rbuf) + { + } + + //-------------------------------------------------------------------- + void clear(const rgba8& c) + { + unsigned y; + for(y = 0; y < m_rbuf->height(); y++) + { + m_span.hline(m_rbuf->row(y), 0, m_rbuf->width(), c); + } + } + + //-------------------------------------------------------------------- + void pixel(int x, int y, const rgba8& c) + { + if(m_rbuf->inbox(x, y)) + { + m_span.hline(m_rbuf->row(y), x, 1, c); + } + } + + //-------------------------------------------------------------------- + rgba8 pixel(int x, int y) const + { + if(m_rbuf->inbox(x, y)) + { + return m_span.get(m_rbuf->row(y), x); + } + return rgba8(0,0,0); + } + + //-------------------------------------------------------------------- + void render(const scanline& sl, const rgba8& c) + { + if(sl.y() < 0 || sl.y() >= int(m_rbuf->height())) + { + return; + } + + unsigned num_spans = sl.num_spans(); + int base_x = sl.base_x(); + unsigned char* row = m_rbuf->row(sl.y()); + scanline::iterator span(sl); + + do + { + int x = span.next() + base_x; + const int8u* covers = span.covers(); + int num_pix = span.num_pix(); + if(x < 0) + { + num_pix += x; + if(num_pix <= 0) continue; + covers -= x; + x = 0; + } + if(x + num_pix >= int(m_rbuf->width())) + { + num_pix = m_rbuf->width() - x; + if(num_pix <= 0) continue; + } + m_span.render(row, x, num_pix, covers, c); + } + while(--num_spans); + } + + //-------------------------------------------------------------------- + rendering_buffer& rbuf() { return *m_rbuf; } + + private: + rendering_buffer* m_rbuf; + Span m_span; + }; + + + //------------------------------------------------------------------------ + // These constants determine the subpixel accuracy, to be more precise, + // the number of bits of the fractional part of the coordinates. + // The possible coordinate capacity in bits can be calculated by formula: + // sizeof(int) * 8 - poly_base_shift * 2, i.e, for 32-bit integers and + // 8-bits fractional part the capacity is 16 bits or [-32768...32767]. + enum + { + poly_base_shift = 8, + poly_base_size = 1 << poly_base_shift, + poly_base_mask = poly_base_size - 1 + }; + + //------------------------------------------------------------------------ + inline int poly_coord(double c) + { + return int(c * poly_base_size); + } + + //------------------------------------------------------------------------ + // A pixel cell. There're no constructors defined and it was done + // intentionally in order to avoid extra overhead when allocating an + // array of cells. + struct cell + { + int16 x; + int16 y; + int packed_coord; + int cover; + int area; + + void set(int x, int y, int c, int a); + void set_coord(int x, int y); + void set_cover(int c, int a); + void add_cover(int c, int a); + }; + + + //------------------------------------------------------------------------ + // An internal class that implements the main rasterization algorithm. + // Used in the rasterizer. Should not be used direcly. + class outline + { + enum + { + cell_block_shift = 12, + cell_block_size = 1 << cell_block_shift, + cell_block_mask = cell_block_size - 1, + cell_block_pool = 256, + cell_block_limit = 1024 + }; + + public: + + ~outline(); + outline(); + + void reset(); + + void move_to(int x, int y); + void line_to(int x, int y); + + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + unsigned num_cells() const {return m_num_cells; } + const cell* const* cells(); + + private: + outline(const outline&); + const outline& operator = (const outline&); + + void set_cur_cell(int x, int y); + void add_cur_cell(); + void sort_cells(); + void render_scanline(int ey, int x1, int y1, int x2, int y2); + void render_line(int x1, int y1, int x2, int y2); + void allocate_block(); + + static void qsort_cells(cell** start, unsigned num); + + private: + unsigned m_num_blocks; + unsigned m_max_blocks; + unsigned m_cur_block; + unsigned m_num_cells; + cell** m_cells; + cell* m_cur_cell_ptr; + cell** m_sorted_cells; + unsigned m_sorted_size; + cell m_cur_cell; + int m_cur_x; + int m_cur_y; + int m_close_x; + int m_close_y; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_flags; + }; + + + //------------------------------------------------------------------------ + enum filling_rule_e + { + fill_non_zero, + fill_even_odd + }; + + + //======================================================================== + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_base_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + class rasterizer + { + public: + enum + { + aa_shift = scanline::aa_shift, + aa_num = 1 << aa_shift, + aa_mask = aa_num - 1, + aa_2num = aa_num * 2, + aa_2mask = aa_2num - 1 + }; + + rasterizer() : + m_filling_rule(fill_non_zero) + { + memcpy(m_gamma, s_default_gamma, sizeof(m_gamma)); + } + + //-------------------------------------------------------------------- + void reset() { m_outline.reset(); } + + //-------------------------------------------------------------------- + void filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //-------------------------------------------------------------------- + void gamma(double g); + void gamma(const int8u* g); + + //-------------------------------------------------------------------- + void move_to(int x, int y) { m_outline.move_to(x, y); } + void line_to(int x, int y) { m_outline.line_to(x, y); } + + //-------------------------------------------------------------------- + void move_to_d(double x, double y) { m_outline.move_to(poly_coord(x), + poly_coord(y)); } + void line_to_d(double x, double y) { m_outline.line_to(poly_coord(x), + poly_coord(y)); } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + int min_y() const { return m_outline.min_y(); } + int max_x() const { return m_outline.max_x(); } + int max_y() const { return m_outline.max_y(); } + + //-------------------------------------------------------------------- + unsigned calculate_alpha(int area) const + { + int cover = area >> (poly_base_shift*2 + 1 - aa_shift); + + if(cover < 0) cover = -cover; + if(m_filling_rule == fill_even_odd) + { + cover &= aa_2mask; + if(cover > aa_num) + { + cover = aa_2num - cover; + } + } + if(cover > aa_mask) cover = aa_mask; + return cover; + } + + //-------------------------------------------------------------------- + template void render(Renderer& r, + const rgba8& c, + int dx=0, + int dy=0) + { + const cell* const* cells = m_outline.cells(); + if(m_outline.num_cells() == 0) return; + + int x, y; + int cover; + int alpha; + int area; + + m_scanline.reset(m_outline.min_x(), m_outline.max_x(), dx, dy); + + cover = 0; + const cell* cur_cell = *cells++; + for(;;) + { + const cell* start_cell = cur_cell; + + int coord = cur_cell->packed_coord; + x = cur_cell->x; + y = cur_cell->y; + + area = start_cell->area; + cover += start_cell->cover; + + //accumulate all start cells + while((cur_cell = *cells++) != 0) + { + if(cur_cell->packed_coord != coord) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area); + if(alpha) + { + if(m_scanline.is_ready(y)) + { + r.render(m_scanline, c); + m_scanline.reset_spans(); + } + m_scanline.add_cell(x, y, m_gamma[alpha]); + } + x++; + } + + if(!cur_cell) break; + + if(cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_base_shift + 1)); + if(alpha) + { + if(m_scanline.is_ready(y)) + { + r.render(m_scanline, c); + m_scanline.reset_spans(); + } + m_scanline.add_span(x, y, + cur_cell->x - x, + m_gamma[alpha]); + } + } + } + + if(m_scanline.num_spans()) + { + r.render(m_scanline, c); + } + } + + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + private: + rasterizer(const rasterizer&); + const rasterizer& operator = (const rasterizer&); + + private: + outline m_outline; + scanline m_scanline; + filling_rule_e m_filling_rule; + int8u m_gamma[256]; + static const int8u s_default_gamma[256]; + }; + + + //======================================================================== + struct span_mono8 + { + //-------------------------------------------------------------------- + static unsigned mono8(unsigned r, unsigned g, unsigned b) + { + return (r * 77 + g * 150 + b * 29) >> 8; + } + + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + x; + unsigned dst = mono8(c.r, c.g, c.b); + do + { + int alpha = (*covers++) * c.a; + unsigned src = *p; + *p++ = (((dst - src) * alpha) + (src << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + x; + unsigned v = mono8(c.r, c.g, c.b); + do { *p++ = v; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned rgb = ptr[x]; + rgba8 c; + c.r = rgb; + c.g = rgb; + c.b = rgb; + c.a = 255; + return c; + } + }; + + + + //======================================================================== + struct span_rgb555 + { + //-------------------------------------------------------------------- + static int16u rgb555(unsigned r, unsigned g, unsigned b) + { + return ((r & 0xF8) << 7) | ((g & 0xF8) << 2) | (b >> 3); + } + + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + int16u* p = ((int16u*)ptr) + x; + do + { + int16 rgb = *p; + int alpha = (*covers++) * c.a; + + int r = (rgb >> 7) & 0xF8; + int g = (rgb >> 2) & 0xF8; + int b = (rgb << 3) & 0xF8; + + *p++ = (((((c.r - r) * alpha) + (r << 16)) >> 9) & 0x7C00) | + (((((c.g - g) * alpha) + (g << 16)) >> 14) & 0x3E0) | + ((((c.b - b) * alpha) + (b << 16)) >> 19); + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + int16u* p = ((int16u*)ptr) + x; + int16u v = rgb555(c.r, c.g, c.b); + do { *p++ = v; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + int16u rgb = ((int16u*)ptr)[x]; + rgba8 c; + c.r = (rgb >> 7) & 0xF8; + c.g = (rgb >> 2) & 0xF8; + c.b = (rgb << 3) & 0xF8; + c.a = 255; + return c; + } + }; + + + + + //======================================================================== + struct span_rgb565 + { + //-------------------------------------------------------------------- + static int16u rgb565(unsigned r, unsigned g, unsigned b) + { + return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); + } + + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + int16u* p = ((int16u*)ptr) + x; + do + { + int16 rgb = *p; + int alpha = (*covers++) * c.a; + + int r = (rgb >> 8) & 0xF8; + int g = (rgb >> 3) & 0xFC; + int b = (rgb << 3) & 0xF8; + + *p++ = (((((c.r - r) * alpha) + (r << 16)) >> 8) & 0xF800) | + (((((c.g - g) * alpha) + (g << 16)) >> 13) & 0x7E0) | + ((((c.b - b) * alpha) + (b << 16)) >> 19); + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + int16u* p = ((int16u*)ptr) + x; + int16u v = rgb565(c.r, c.g, c.b); + do { *p++ = v; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + int16u rgb = ((int16u*)ptr)[x]; + rgba8 c; + c.r = (rgb >> 8) & 0xF8; + c.g = (rgb >> 3) & 0xFC; + c.b = (rgb << 3) & 0xF8; + c.a = 255; + return c; + } + }; + + + + //======================================================================== + struct span_bgr24 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + x + x + x; + do + { + int alpha = (*covers++) * c.a; + int b = p[0]; + int g = p[1]; + int r = p[2]; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + x + x + x; + do { *p++ = c.b; *p++ = c.g; *p++ = c.r; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + x + x + x; + rgba8 c; + c.b = *p++; + c.g = *p++; + c.r = *p++; + c.a = 255; + return c; + } + }; + + + + //======================================================================== + struct span_rgb24 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + x + x + x; + do + { + int alpha = (*covers++) * c.a; + int r = p[0]; + int g = p[1]; + int b = p[2]; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + x + x + x; + do { *p++ = c.r; *p++ = c.g; *p++ = c.b; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + x + x + x; + rgba8 c; + c.r = *p++; + c.g = *p++; + c.b = *p++; + c.a = 255; + return c; + } + }; + + + + //======================================================================== + struct span_abgr32 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do + { + int alpha = (*covers++) * c.a; + int a = p[0]; + int b = p[1]; + int g = p[2]; + int r = p[3]; + *p++ = (((c.a - a) * alpha) + (a << 16)) >> 16; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do { *p++ = c.a; *p++ = c.b; *p++ = c.g; *p++ = c.r; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + (x << 2); + rgba8 c; + c.a = *p++; + c.b = *p++; + c.g = *p++; + c.r = *p; + return c; + } + }; + + + + + //======================================================================== + struct span_argb32 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do + { + int alpha = (*covers++) * c.a; + int a = p[0]; + int r = p[1]; + int g = p[2]; + int b = p[3]; + *p++ = (((c.a - a) * alpha) + (a << 16)) >> 16; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do { *p++ = c.a; *p++ = c.r; *p++ = c.g; *p++ = c.b; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + (x << 2); + rgba8 c; + c.a = *p++; + c.r = *p++; + c.g = *p++; + c.b = *p; + return c; + } + }; + + + + //======================================================================== + struct span_bgra32 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do + { + int alpha = (*covers++) * c.a; + int b = p[0]; + int g = p[1]; + int r = p[2]; + int a = p[3]; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + *p++ = (((c.a - a) * alpha) + (a << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do { *p++ = c.b; *p++ = c.g; *p++ = c.r; *p++ = c.a; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + (x << 2); + rgba8 c; + c.b = *p++; + c.g = *p++; + c.r = *p++; + c.a = *p; + return c; + } + }; + + + + + //======================================================================== + struct span_rgba32 + { + //-------------------------------------------------------------------- + static void render(unsigned char* ptr, + int x, + unsigned count, + const unsigned char* covers, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do + { + int alpha = (*covers++) * c.a; + int r = p[0]; + int g = p[1]; + int b = p[2]; + int a = p[3]; + *p++ = (((c.r - r) * alpha) + (r << 16)) >> 16; + *p++ = (((c.g - g) * alpha) + (g << 16)) >> 16; + *p++ = (((c.b - b) * alpha) + (b << 16)) >> 16; + *p++ = (((c.a - a) * alpha) + (a << 16)) >> 16; + } + while(--count); + } + + //-------------------------------------------------------------------- + static void hline(unsigned char* ptr, + int x, + unsigned count, + const rgba8& c) + { + unsigned char* p = ptr + (x << 2); + do { *p++ = c.r; *p++ = c.g; *p++ = c.b; *p++ = c.a; } while(--count); + } + + //-------------------------------------------------------------------- + static rgba8 get(unsigned char* ptr, int x) + { + unsigned char* p = ptr + (x << 2); + rgba8 c; + c.r = *p++; + c.g = *p++; + c.b = *p++; + c.a = *p; + return c; + } + }; + + +} + + + +#endif + diff --git a/libfreetype/Makefile b/libfreetype/Makefile deleted file mode 100644 index 5db2066..0000000 --- a/libfreetype/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -MISPDIR=.. -include $(MISPDIR)/common.mak - -CFLAGS+=-Iinclude -I$(FTDIR)/include -include $(FTDIR)/include/freetype/internal/internal.h - -FTSRC=$(FTDIR)/src - -OBJECTS=ftadvanc.o ftcalc.o ftdbgmem.o ftgloadr.o ftobjs.o ftoutln.o ftrfork.o ftsnames.o ftstream.o fttrigon.o ftutil.o -OBJECTS+=ftbbox.o ftfstype.o ftgasp.o ftglyph.o ftgxval.o ftlcdfil.o ftmm.o ftotval.o ftstroke.o ftbitmap.o ftsynth.o -OBJECTS+=ftsystem.o ftdebug.o ftinit.o -%.o: $(FTSRC)/base/%.c - $(compile-dep) - -OBJECTS+=ttdriver.o ttgload.o ttgxvar.o ttinterp.o ttobjs.o ttpic.o ttpload.o -%.o: $(FTSRC)/truetype/%.c - $(compile-dep) - -OBJECTS+=afangles.o afcjk.o afdummy.o afglobal.o afhints.o afindic.o aflatin.o afloader.o afmodule.o afpic.o afwarp.o -%.o: $(FTSRC)/autofit/%.c - $(compile-dep) - -OBJECTS+=ftraster.o ftrend1.o rastpic.o -%.o: $(FTSRC)/raster/%.c - $(compile-dep) - -OBJECTS+=ftgrays.o ftsmooth.o ftspic.o -%.o: $(FTSRC)/smooth/%.c - $(compile-dep) - -OBJECTS+=ftcbasic.o ftccache.o ftccmap.o ftcglyph.o ftcimage.o ftcmanag.o ftcmru.o ftcsbits.o -%.o: $(FTSRC)/cache/%.c - $(compile-dep) - -all: libfreetype.a - -# pull in dependency info for *existing* .o files --include $(OBJECTS:.o=.d) - -libfreetype.a: $(OBJECTS) - $(AR) clr libfreetype.a $(OBJECTS) - $(RANLIB) libfreetype.a - -.PHONY: clean - -clean: - rm -f $(OBJECTS) $(OBJECTS:.o=.d) libfreetype.a .*~ *~ diff --git a/libfreetype/include/freetype/config/ftmodule.h b/libfreetype/include/freetype/config/ftmodule.h deleted file mode 100644 index 3694aa5..0000000 --- a/libfreetype/include/freetype/config/ftmodule.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * This file registers the FreeType modules compiled into the library. - * - * If you use GNU make, this file IS NOT USED! Instead, it is created in - * the objects directory (normally `/objs/') based on information - * from `/modules.cfg'. - * - * Please read `docs/INSTALL.ANY' and `docs/CUSTOMIZE' how to compile - * FreeType without GNU make. - * - */ - -FT_USE_MODULE( FT_Module_Class, autofit_module_class ) -FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class ) -FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class ) - -/* EOF */ diff --git a/libfreetype/include/freetype/config/ftoption.h b/libfreetype/include/freetype/config/ftoption.h deleted file mode 100644 index ab5b0cb..0000000 --- a/libfreetype/include/freetype/config/ftoption.h +++ /dev/null @@ -1,805 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftoption.h */ -/* */ -/* User-selectable configuration macros (specification only). */ -/* */ -/* Copyright 1996-2011 by */ -/* David Turner, Robert Wilhelm, and Werner Lemberg. */ -/* */ -/* This file is part of the FreeType project, and may only be used, */ -/* modified, and distributed under the terms of the FreeType project */ -/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ -/* this file you indicate that you have read the license and */ -/* understand and accept it fully. */ -/* */ -/***************************************************************************/ - - -#ifndef __FTOPTION_H__ -#define __FTOPTION_H__ - - -#include - - -FT_BEGIN_HEADER - - /*************************************************************************/ - /* */ - /* USER-SELECTABLE CONFIGURATION MACROS */ - /* */ - /* This file contains the default configuration macro definitions for */ - /* a standard build of the FreeType library. There are three ways to */ - /* use this file to build project-specific versions of the library: */ - /* */ - /* - You can modify this file by hand, but this is not recommended in */ - /* cases where you would like to build several versions of the */ - /* library from a single source directory. */ - /* */ - /* - You can put a copy of this file in your build directory, more */ - /* precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD' */ - /* is the name of a directory that is included _before_ the FreeType */ - /* include path during compilation. */ - /* */ - /* The default FreeType Makefiles and Jamfiles use the build */ - /* directory `builds/' by default, but you can easily change */ - /* that for your own projects. */ - /* */ - /* - Copy the file to `$BUILD/ft2build.h' and modify it */ - /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ - /* locate this file during the build. For example, */ - /* */ - /* #define FT_CONFIG_OPTIONS_H */ - /* #include */ - /* */ - /* will use `$BUILD/myftoptions.h' instead of this file for macro */ - /* definitions. */ - /* */ - /* Note also that you can similarly pre-define the macro */ - /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ - /* that are statically linked to the library at compile time. By */ - /* default, this file is . */ - /* */ - /* We highly recommend using the third method whenever possible. */ - /* */ - /*************************************************************************/ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Uncomment the line below if you want to activate sub-pixel rendering */ - /* (a.k.a. LCD rendering, or ClearType) in this build of the library. */ - /* */ - /* Note that this feature is covered by several Microsoft patents */ - /* and should not be activated in any default build of the library. */ - /* */ - /* This macro has no impact on the FreeType API, only on its */ - /* _implementation_. For example, using FT_RENDER_MODE_LCD when calling */ - /* FT_Render_Glyph still generates a bitmap that is 3 times wider than */ - /* the original size in case this macro isn't defined; however, each */ - /* triplet of subpixels has R=G=B. */ - /* */ - /* This is done to allow FreeType clients to run unmodified, forcing */ - /* them to display normal gray-level anti-aliased glyphs. */ - /* */ -/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ - - - /*************************************************************************/ - /* */ - /* Many compilers provide a non-ANSI 64-bit data type that can be used */ - /* by FreeType to speed up some computations. However, this will create */ - /* some problems when compiling the library in strict ANSI mode. */ - /* */ - /* For this reason, the use of 64-bit integers is normally disabled when */ - /* the __STDC__ macro is defined. You can however disable this by */ - /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ - /* */ - /* For most compilers, this will only create compilation warnings when */ - /* building the library. */ - /* */ - /* ObNote: The compiler-specific 64-bit integers are detected in the */ - /* file `ftconfig.h' either statically or through the */ - /* `configure' script on supported platforms. */ - /* */ -#undef FT_CONFIG_OPTION_FORCE_INT64 - - - /*************************************************************************/ - /* */ - /* If this macro is defined, do not try to use an assembler version of */ - /* performance-critical functions (e.g. FT_MulFix). You should only do */ - /* that to verify that the assembler function works properly, or to */ - /* execute benchmark tests of the various implementations. */ -/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */ - - - /*************************************************************************/ - /* */ - /* If this macro is defined, try to use an inlined assembler version of */ - /* the `FT_MulFix' function, which is a `hotspot' when loading and */ - /* hinting glyphs, and which should be executed as fast as possible. */ - /* */ - /* Note that if your compiler or CPU is not supported, this will default */ - /* to the standard and portable implementation found in `ftcalc.c'. */ - /* */ -#define FT_CONFIG_OPTION_INLINE_MULFIX - - - /*************************************************************************/ - /* */ - /* LZW-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `compress' program. This is mostly used to parse many of the PCF */ - /* files that come with various X11 distributions. The implementation */ - /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ - /* (see src/lzw/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -//#define FT_CONFIG_OPTION_USE_LZW - - - /*************************************************************************/ - /* */ - /* Gzip-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `gzip' program. This is mostly used to parse many of the PCF files */ - /* that come with XFree86. The implementation uses `zlib' to */ - /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ - /* */ - /* Define this macro if you want to enable this `feature'. See also */ - /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ - /* */ -//#define FT_CONFIG_OPTION_USE_ZLIB - - - /*************************************************************************/ - /* */ - /* ZLib library selection */ - /* */ - /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ - /* It allows FreeType's `ftgzip' component to link to the system's */ - /* installation of the ZLib library. This is useful on systems like */ - /* Unix or VMS where it generally is already available. */ - /* */ - /* If you let it undefined, the component will use its own copy */ - /* of the zlib sources instead. These have been modified to be */ - /* included directly within the component and *not* export external */ - /* function names. This allows you to link any program with FreeType */ - /* _and_ ZLib without linking conflicts. */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ - - - /*************************************************************************/ - /* */ - /* Bzip2-compressed file support. */ - /* */ - /* FreeType now handles font files that have been compressed with the */ - /* `bzip2' program. This is mostly used to parse many of the PCF */ - /* files that come with XFree86. The implementation uses `libbz2' to */ - /* partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */ - /* Contrary to gzip, bzip2 currently is not included and need to use */ - /* the system available bzip2 implementation. */ - /* */ - /* Define this macro if you want to enable this `feature'. */ - /* */ -/* #define FT_CONFIG_OPTION_USE_BZIP2 */ - - - /*************************************************************************/ - /* */ - /* Define to disable the use of file stream functions and types, FILE, */ - /* fopen() etc. Enables the use of smaller system libraries on embedded */ - /* systems that have multiple system libraries, some with or without */ - /* file stream support, in the cases where file stream support is not */ - /* necessary such as memory loading of font files. */ - /* */ -/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */ - - - /*************************************************************************/ - /* */ - /* DLL export compilation */ - /* */ - /* When compiling FreeType as a DLL, some systems/compilers need a */ - /* special keyword in front OR after the return type of function */ - /* declarations. */ - /* */ - /* Two macros are used within the FreeType source code to define */ - /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ - /* */ - /* FT_EXPORT( return_type ) */ - /* */ - /* is used in a function declaration, as in */ - /* */ - /* FT_EXPORT( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ); */ - /* */ - /* */ - /* FT_EXPORT_DEF( return_type ) */ - /* */ - /* is used in a function definition, as in */ - /* */ - /* FT_EXPORT_DEF( FT_Error ) */ - /* FT_Init_FreeType( FT_Library* alibrary ) */ - /* { */ - /* ... some code ... */ - /* return FT_Err_Ok; */ - /* } */ - /* */ - /* You can provide your own implementation of FT_EXPORT and */ - /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ - /* will be later automatically defined as `extern return_type' to */ - /* allow normal compilation. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_EXPORT(x) extern x */ -/* #define FT_EXPORT_DEF(x) x */ - - - /*************************************************************************/ - /* */ - /* Glyph Postscript Names handling */ - /* */ - /* By default, FreeType 2 is compiled with the `psnames' module. This */ - /* module is in charge of converting a glyph name string into a */ - /* Unicode value, or return a Macintosh standard glyph name for the */ - /* use with the TrueType `post' table. */ - /* */ - /* Undefine this macro if you do not want `psnames' compiled in your */ - /* build of FreeType. This has the following effects: */ - /* */ - /* - The TrueType driver will provide its own set of glyph names, */ - /* if you build it to support postscript names in the TrueType */ - /* `post' table. */ - /* */ - /* - The Type 1 driver will not be able to synthesize a Unicode */ - /* charmap out of the glyphs found in the fonts. */ - /* */ - /* You would normally undefine this configuration macro when building */ - /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ - /* */ -//#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Postscript Names to Unicode Values support */ - /* */ - /* By default, FreeType 2 is built with the `PSNames' module compiled */ - /* in. Among other things, the module is used to convert a glyph name */ - /* into a Unicode value. This is especially useful in order to */ - /* synthesize on the fly a Unicode charmap from the CFF/Type 1 driver */ - /* through a big table named the `Adobe Glyph List' (AGL). */ - /* */ - /* Undefine this macro if you do not want the Adobe Glyph List */ - /* compiled in your `PSNames' module. The Type 1 driver will not be */ - /* able to synthesize a Unicode charmap out of the glyphs found in the */ - /* fonts. */ - /* */ -//#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST - - - /*************************************************************************/ - /* */ - /* Support for Mac fonts */ - /* */ - /* Define this macro if you want support for outline fonts in Mac */ - /* format (mac dfont, mac resource, macbinary containing a mac */ - /* resource) on non-Mac platforms. */ - /* */ - /* Note that the `FOND' resource isn't checked. */ - /* */ -//#define FT_CONFIG_OPTION_MAC_FONTS - - - /*************************************************************************/ - /* */ - /* Guessing methods to access embedded resource forks */ - /* */ - /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ - /* GNU/Linux). */ - /* */ - /* Resource forks which include fonts data are stored sometimes in */ - /* locations which users or developers don't expected. In some cases, */ - /* resource forks start with some offset from the head of a file. In */ - /* other cases, the actual resource fork is stored in file different */ - /* from what the user specifies. If this option is activated, */ - /* FreeType tries to guess whether such offsets or different file */ - /* names must be used. */ - /* */ - /* Note that normal, direct access of resource forks is controlled via */ - /* the FT_CONFIG_OPTION_MAC_FONTS option. */ - /* */ -#ifdef FT_CONFIG_OPTION_MAC_FONTS -#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK -#endif - - - /*************************************************************************/ - /* */ - /* Allow the use of FT_Incremental_Interface to load typefaces that */ - /* contain no glyph data, but supply it via a callback function. */ - /* This is required by clients supporting document formats which */ - /* supply font data incrementally as the document is parsed, such */ - /* as the Ghostscript interpreter for the PostScript language. */ - /* */ -#define FT_CONFIG_OPTION_INCREMENTAL - - - /*************************************************************************/ - /* */ - /* The size in bytes of the render pool used by the scan-line converter */ - /* to do all of its work. */ - /* */ - /* This must be greater than 4KByte if you use FreeType to rasterize */ - /* glyphs; otherwise, you may set it to zero to avoid unnecessary */ - /* allocation of the render pool. */ - /* */ -#define FT_RENDER_POOL_SIZE 16384L - - - /*************************************************************************/ - /* */ - /* FT_MAX_MODULES */ - /* */ - /* The maximum number of modules that can be registered in a single */ - /* FreeType library object. 32 is the default. */ - /* */ -#define FT_MAX_MODULES 32 - - - /*************************************************************************/ - /* */ - /* Debug level */ - /* */ - /* FreeType can be compiled in debug or trace mode. In debug mode, */ - /* errors are reported through the `ftdebug' component. In trace */ - /* mode, additional messages are sent to the standard output during */ - /* execution. */ - /* */ - /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ - /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ - /* */ - /* Don't define any of these macros to compile in `release' mode! */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_LEVEL_ERROR */ -/* #define FT_DEBUG_LEVEL_TRACE */ - - - /*************************************************************************/ - /* */ - /* Autofitter debugging */ - /* */ - /* If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to */ - /* control the autofitter behaviour for debugging purposes with global */ - /* boolean variables (consequently, you should *never* enable this */ - /* while compiling in `release' mode): */ - /* */ - /* _af_debug_disable_horz_hints */ - /* _af_debug_disable_vert_hints */ - /* _af_debug_disable_blue_hints */ - /* */ - /* Additionally, the following functions provide dumps of various */ - /* internal autofit structures to stdout (using `printf'): */ - /* */ - /* af_glyph_hints_dump_points */ - /* af_glyph_hints_dump_segments */ - /* af_glyph_hints_dump_edges */ - /* */ - /* As an argument, they use another global variable: */ - /* */ - /* _af_debug_hints */ - /* */ - /* Please have a look at the `ftgrid' demo program to see how those */ - /* variables and macros should be used. */ - /* */ - /* Do not #undef these macros here since the build system might define */ - /* them for certain configurations only. */ - /* */ -/* #define FT_DEBUG_AUTOFIT */ - - - /*************************************************************************/ - /* */ - /* Memory Debugging */ - /* */ - /* FreeType now comes with an integrated memory debugger that is */ - /* capable of detecting simple errors like memory leaks or double */ - /* deletes. To compile it within your build of the library, you */ - /* should define FT_DEBUG_MEMORY here. */ - /* */ - /* Note that the memory debugger is only activated at runtime when */ - /* when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */ - /* */ - /* Do not #undef this macro here since the build system might define */ - /* it for certain configurations only. */ - /* */ -/* #define FT_DEBUG_MEMORY */ - - - /*************************************************************************/ - /* */ - /* Module errors */ - /* */ - /* If this macro is set (which is _not_ the default), the higher byte */ - /* of an error code gives the module in which the error has occurred, */ - /* while the lower byte is the real error code. */ - /* */ - /* Setting this macro makes sense for debugging purposes only, since */ - /* it would break source compatibility of certain programs that use */ - /* FreeType 2. */ - /* */ - /* More details can be found in the files ftmoderr.h and fterrors.h. */ - /* */ -#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS - - - /*************************************************************************/ - /* */ - /* Position Independent Code */ - /* */ - /* If this macro is set (which is _not_ the default), FreeType2 will */ - /* avoid creating constants that require address fixups. Instead the */ - /* constants will be moved into a struct and additional intialization */ - /* code will be used. */ - /* */ - /* Setting this macro is needed for systems that prohibit address */ - /* fixups, such as BREW. */ - /* */ -/* #define FT_CONFIG_OPTION_PIC */ - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ - /* embedded bitmaps in all formats using the SFNT module (namely */ - /* TrueType & OpenType). */ - /* */ -#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ - /* load and enumerate the glyph Postscript names in a TrueType or */ - /* OpenType file. */ - /* */ - /* Note that when you do not compile the `PSNames' module by undefining */ - /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ - /* contain additional code used to read the PS Names table from a font. */ - /* */ - /* (By default, the module uses `PSNames' to extract glyph names.) */ - /* */ -#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ - /* access the internal name table in a SFNT-based format like TrueType */ - /* or OpenType. The name table contains various strings used to */ - /* describe the font, like family name, copyright, version, etc. It */ - /* does not contain any glyph name though. */ - /* */ - /* Accessing SFNT names is done through the functions declared in */ - /* `freetype/ftsnames.h'. */ - /* */ -#define TT_CONFIG_OPTION_SFNT_NAMES - - - /*************************************************************************/ - /* */ - /* TrueType CMap support */ - /* */ - /* Here you can fine-tune which TrueType CMap table format shall be */ - /* supported. */ -#define TT_CONFIG_CMAP_FORMAT_0 -#define TT_CONFIG_CMAP_FORMAT_2 -#define TT_CONFIG_CMAP_FORMAT_4 -#define TT_CONFIG_CMAP_FORMAT_6 -#define TT_CONFIG_CMAP_FORMAT_8 -#define TT_CONFIG_CMAP_FORMAT_10 -#define TT_CONFIG_CMAP_FORMAT_12 -#define TT_CONFIG_CMAP_FORMAT_13 -#define TT_CONFIG_CMAP_FORMAT_14 - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ - /* a bytecode interpreter in the TrueType driver. */ - /* */ - /* By undefining this, you will only compile the code necessary to load */ - /* TrueType glyphs without hinting. */ - /* */ - /* Do not #undef this macro here, since the build system might */ - /* define it for certain configurations only. */ - /* */ -#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER - - - /*************************************************************************/ - /* */ - /* If you define TT_CONFIG_OPTION_UNPATENTED_HINTING, a special version */ - /* of the TrueType bytecode interpreter is used that doesn't implement */ - /* any of the patented opcodes and algorithms. The patents related to */ - /* TrueType hinting have expired worldwide since May 2010; this option */ - /* is now deprecated. */ - /* */ - /* Note that the TT_CONFIG_OPTION_UNPATENTED_HINTING macro is *ignored* */ - /* if you define TT_CONFIG_OPTION_BYTECODE_INTERPRETER; in other words, */ - /* either define TT_CONFIG_OPTION_BYTECODE_INTERPRETER or */ - /* TT_CONFIG_OPTION_UNPATENTED_HINTING but not both at the same time. */ - /* */ - /* This macro is only useful for a small number of font files (mostly */ - /* for Asian scripts) that require bytecode interpretation to properly */ - /* load glyphs. For all other fonts, this produces unpleasant results, */ - /* thus the unpatented interpreter is never used to load glyphs from */ - /* TrueType fonts unless one of the following two options is used. */ - /* */ - /* - The unpatented interpreter is explicitly activated by the user */ - /* through the FT_PARAM_TAG_UNPATENTED_HINTING parameter tag */ - /* when opening the FT_Face. */ - /* */ - /* - FreeType detects that the FT_Face corresponds to one of the */ - /* `trick' fonts (e.g., `Mingliu') it knows about. The font engine */ - /* contains a hard-coded list of font names and other matching */ - /* parameters (see function `tt_face_init' in file */ - /* `src/truetype/ttobjs.c'). */ - /* */ - /* Here a sample code snippet for using FT_PARAM_TAG_UNPATENTED_HINTING. */ - /* */ - /* { */ - /* FT_Parameter parameter; */ - /* FT_Open_Args open_args; */ - /* */ - /* */ - /* parameter.tag = FT_PARAM_TAG_UNPATENTED_HINTING; */ - /* */ - /* open_args.flags = FT_OPEN_PATHNAME | FT_OPEN_PARAMS; */ - /* open_args.pathname = my_font_pathname; */ - /* open_args.num_params = 1; */ - /* open_args.params = ¶meter; */ - /* */ - /* error = FT_Open_Face( library, &open_args, index, &face ); */ - /* ... */ - /* } */ - /* */ -/* #define TT_CONFIG_OPTION_UNPATENTED_HINTING */ - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ - /* bytecode interpreter with a huge switch statement, rather than a call */ - /* table. This results in smaller and faster code for a number of */ - /* architectures. */ - /* */ - /* Note however that on some compiler/processor combinations, undefining */ - /* this macro will generate faster, though larger, code. */ - /* */ -#define TT_CONFIG_OPTION_INTERPRETER_SWITCH - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ - /* TrueType glyph loader to use Apple's definition of how to handle */ - /* component offsets in composite glyphs. */ - /* */ - /* Apple and MS disagree on the default behavior of component offsets */ - /* in composites. Apple says that they should be scaled by the scaling */ - /* factors in the transformation matrix (roughly, it's more complex) */ - /* while MS says they should not. OpenType defines two bits in the */ - /* composite flags array which can be used to disambiguate, but old */ - /* fonts will not have them. */ - /* */ - /* http://www.microsoft.com/typography/otspec/glyf.htm */ - /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ - /* */ -#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include */ - /* support for Apple's distortable font technology (fvar, gvar, cvar, */ - /* and avar tables). This has many similarities to Type 1 Multiple */ - /* Masters support. */ - /* */ -#define TT_CONFIG_OPTION_GX_VAR_SUPPORT - - - /*************************************************************************/ - /* */ - /* Define TT_CONFIG_OPTION_BDF if you want to include support for */ - /* an embedded `BDF ' table within SFNT-based bitmap formats. */ - /* */ -#define TT_CONFIG_OPTION_BDF - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ - /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ - /* required. */ - /* */ -#define T1_MAX_DICT_DEPTH 5 - - - /*************************************************************************/ - /* */ - /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ - /* calls during glyph loading. */ - /* */ -#define T1_MAX_SUBRS_CALLS 16 - - - /*************************************************************************/ - /* */ - /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ - /* minimum of 16 is required. */ - /* */ - /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ - /* */ -#define T1_MAX_CHARSTRINGS_OPERANDS 256 - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ - /* files into an existing face. Note that if set, the T1 driver will be */ - /* unable to produce kerning distances. */ - /* */ -#undef T1_CONFIG_OPTION_NO_AFM - - - /*************************************************************************/ - /* */ - /* Define this configuration macro if you want to prevent the */ - /* compilation of the Multiple Masters font support in the Type 1 */ - /* driver. */ - /* */ -#undef T1_CONFIG_OPTION_NO_MM_SUPPORT - - - /*************************************************************************/ - /*************************************************************************/ - /**** ****/ - /**** A U T O F I T M O D U L E C O N F I G U R A T I O N ****/ - /**** ****/ - /*************************************************************************/ - /*************************************************************************/ - - - /*************************************************************************/ - /* */ - /* Compile autofit module with CJK (Chinese, Japanese, Korean) script */ - /* support. */ - /* */ -#define AF_CONFIG_OPTION_CJK - - /*************************************************************************/ - /* */ - /* Compile autofit module with Indic script support. */ - /* */ -#define AF_CONFIG_OPTION_INDIC - - /*************************************************************************/ - /* */ - /* Compile autofit module with warp hinting. The idea of the warping */ - /* code is to slightly scale and shift a glyph within a single dimension */ - /* so that as much of its segments are aligned (more or less) on the */ - /* grid. To find out the optimal scaling and shifting value, various */ - /* parameter combinations are tried and scored. */ - /* */ - /* This experimental option is only active if the render mode is */ - /* FT_RENDER_MODE_LIGHT. */ - /* */ -/* #define AF_CONFIG_OPTION_USE_WARPER */ - - /* */ - - - /* - * Define this variable if you want to keep the layout of internal - * structures that was used prior to FreeType 2.2. This also compiles in - * a few obsolete functions to avoid linking problems on typical Unix - * distributions. - * - * For embedded systems or building a new distribution from scratch, it - * is recommended to disable the macro since it reduces the library's code - * size and activates a few memory-saving optimizations as well. - */ -#define FT_CONFIG_OPTION_OLD_INTERNALS - - - /* - * To detect legacy cache-lookup call from a rogue client (<= 2.1.7), - * we restrict the number of charmaps in a font. The current API of - * FTC_CMapCache_Lookup() takes cmap_index & charcode, but old API - * takes charcode only. To determine the passed value is for cmap_index - * or charcode, the possible cmap_index is restricted not to exceed - * the minimum possible charcode by a rogue client. It is also very - * unlikely that a rogue client is interested in Unicode values 0 to 15. - * - * NOTE: The original threshold was 4 deduced from popular number of - * cmap subtables in UCS-4 TrueType fonts, but now it is not - * irregular for OpenType fonts to have more than 4 subtables, - * because variation selector subtables are available for Apple - * and Microsoft platforms. - */ - -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS -#define FT_MAX_CHARMAP_CACHEABLE 15 -#endif - - - /* - * This macro is defined if either unpatented or native TrueType - * hinting is requested by the definitions above. - */ -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER -#define TT_USE_BYTECODE_INTERPRETER -#undef TT_CONFIG_OPTION_UNPATENTED_HINTING -#elif defined TT_CONFIG_OPTION_UNPATENTED_HINTING -#define TT_USE_BYTECODE_INTERPRETER -#endif - -FT_END_HEADER - - -#endif /* __FTOPTION_H__ */ - - -/* END */ diff --git a/main.c b/main.c index f06a710..ccc63c1 100644 --- a/main.c +++ b/main.c @@ -56,6 +56,8 @@ static void test_lua(void) extern void *_heapstart; +extern void agg_test(void); + int main() { irq_setmask(0); @@ -66,6 +68,7 @@ int main() printf("Hello World\n"); test_lua(); + agg_test(); while(1);