diff --git a/ChangeLog b/ChangeLog index 0d1fa80..7b1eb01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,3 +36,7 @@ 2018-12-1: Version 2.3.2 Update code version 2.3.2 Fix build script and fontconfig code. + +2023-2-17: Version 2.5.0 + Update code version 2.5.0 + Full support macosx system. diff --git a/configure.in b/configure.in index 5407f74..d04ec2e 100644 --- a/configure.in +++ b/configure.in @@ -2,11 +2,11 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(picasso, 2.3, onecoolx@gmail.com) +AC_INIT(picasso, 2.5, onecoolx@gmail.com) VERSION_MAJOR=2 -VERSION_MINOR=3 -VERSION_MICRO=2 +VERSION_MINOR=5 +VERSION_MICRO=0 VERSION=$VERSION_MAJOR.$VERSION_MINOR.$VERSION_MICRO AC_SUBST(VERSION_MAJOR) AC_SUBST(VERSION_MINOR) diff --git a/src/core/graphic_path.cpp b/src/core/graphic_path.cpp index b31e353..eaebf44 100644 --- a/src/core/graphic_path.cpp +++ b/src/core/graphic_path.cpp @@ -530,7 +530,7 @@ unsigned int graphic_path::perceive_polygon_orientation(unsigned int start, unsi unsigned int i; for (i = 0; i < np; i++) { scalar x1, y1, x2, y2; - m_impl->vertex(start + i, &x1, &y1); + m_impl->vertex(start + i, &x1, &y1); m_impl->vertex(start + (i + 1) % np, &x2, &y2); area += x1 * y2 - y1 * x2; } diff --git a/src/gfx/gfx_font_adapter_apple.m b/src/gfx/gfx_font_adapter_apple.m deleted file mode 100644 index 345d623..0000000 --- a/src/gfx/gfx_font_adapter_apple.m +++ /dev/null @@ -1,4 +0,0 @@ -// Created by zhangjipeng on 2023/2/1. -// Copyright © 2023 zhang jipeng. All rights reserved. - -#import diff --git a/src/gfx/gfx_font_adapter_apple.mm b/src/gfx/gfx_font_adapter_apple.mm new file mode 100644 index 0000000..2e4efb7 --- /dev/null +++ b/src/gfx/gfx_font_adapter_apple.mm @@ -0,0 +1,250 @@ +/* Picasso - a vector graphics library + * + * Copyright (C) 2023 Zhang Ji Peng + * Contact: onecoolx@gmail.com + */ + +#include +#include "common.h" +#include "convert.h" +#include "gfx_font_adapter.h" +#include "gfx_rasterizer_scanline.h" +#include "gfx_scanline.h" +#include "gfx_scanline_renderer.h" +#include "gfx_scanline_storage.h" +#include "gfx_trans_affine.h" + +#import +#import + +#include "graphic_path.h" +#include "graphic_helper.h" +#include "graphic_base.h" + +namespace gfx { + +class font_adapter_impl +{ +public: + font_adapter_impl() + : font(0) + , cur_glyph_index(0) + , cur_data_size(0) + , flip_y(false) + , weight(0) + , height(0) + , ascent(0) + , descent(0) + , leading(0) + , units_per_em(0) + , cur_bound_rect(0, 0, 0, 0) + , cur_advance_x(0) + , cur_advance_y(0) + { + } + + ~font_adapter_impl() + { + if (font) { + CFRelease(font); + } + font = 0; + } + + CTFontRef font; + CGAffineTransform matrix; + CGGlyph cur_glyph_index; + unsigned int cur_data_size; + bool flip_y; + scalar weight; + scalar height; + scalar ascent; + scalar descent; + scalar leading; + unsigned int units_per_em; + + picasso::graphic_path cur_font_path; + rect cur_bound_rect; + scalar cur_advance_x; + scalar cur_advance_y; +}; + +gfx_font_adapter::gfx_font_adapter(const char* name, int charset, scalar size, scalar weight, + bool italic, bool hint, bool flip, bool a, const abstract_trans_affine* mtx) + :m_impl(new font_adapter_impl) +{ + CFStringRef fName = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + m_impl->matrix = CGAffineTransformMake(mtx->sx(), mtx->shy(), mtx->shx(), mtx->sy(), mtx->tx(), mtx->ty()); + CTFontOptions opt = kCTFontOptionsPreferSystemFont; + m_impl->font = CTFontCreateWithNameAndOptions(fName, (CGFloat)size, &(m_impl->matrix), opt); + m_impl->flip_y = flip; + if ((CTFontGetSymbolicTraits(m_impl->font) & kCTFontTraitItalic) == 0 && italic) { + m_impl->matrix = CGAffineTransformConcat(m_impl->matrix, CGAffineTransformMake(1.0, 0.0, 0.4, 1.0, 0.0, 0.0)); + } + // FIXME: weight not implement. + CFRelease(fName); +} + +gfx_font_adapter::~gfx_font_adapter() +{ + delete m_impl; +} + +static void _cgPathReader(void *info, const CGPathElement *element) +{ + font_adapter_impl* imp = (font_adapter_impl*)info; + picasso::graphic_path* path = (picasso::graphic_path*)(&(imp->cur_font_path)); + bool flip_y = imp->flip_y; + + switch (element->type) { + case kCGPathElementMoveToPoint: + { + CGPoint* p = element->points; + path->move_to((scalar)p[0].x, flip_y ? -(scalar)p[0].y : (scalar)p[0].y); + break; + } + case kCGPathElementAddLineToPoint: + { + CGPoint* p = element->points; + path->line_to((scalar)p[0].x, flip_y ? -(scalar)p[0].y : (scalar)p[0].y); + break; + } + case kCGPathElementAddCurveToPoint: + { + CGPoint* p = element->points; + path->add_vertex((scalar)p[0].x, flip_y ? -(scalar)p[0].y : (scalar)p[0].y, path_cmd_curve4); + path->add_vertex((scalar)p[1].x, flip_y ? -(scalar)p[1].y : (scalar)p[1].y, path_cmd_curve4); + path->add_vertex((scalar)p[2].x, flip_y ? -(scalar)p[2].y : (scalar)p[2].y, path_cmd_curve4); + break; + } + case kCGPathElementAddQuadCurveToPoint: + { + CGPoint* p = element->points; + path->add_vertex((scalar)p[0].x, flip_y ? -(scalar)p[0].y : (scalar)p[0].y, path_cmd_curve3); + path->add_vertex((scalar)p[1].x, flip_y ? -(scalar)p[1].y : (scalar)p[1].y, path_cmd_curve3); + break; + } + case kCGPathElementCloseSubpath: + { + path->close_polygon(); + break; + } + } +} + +static rect get_bounding_rect(graphic_path& path) +{ + rect_s rc(0,0,0,0); + bounding_rect(path, 0, &rc.x1, &rc.y1, &rc.x2, &rc.y2); + return rect((int)Floor(rc.x1), (int)Floor(rc.y1), (int)Ceil(rc.x2), (int)Ceil(rc.y2)); +} + +bool gfx_font_adapter::prepare_glyph(unsigned int code) +{ + if (m_impl->font) { + UniChar charCode = (UniChar)code; + if (!CTFontGetGlyphsForCharacters(m_impl->font, &charCode, &(m_impl->cur_glyph_index), 1)) { + return false; + } + + CGSize advances; + CTFontGetAdvancesForGlyphs(m_impl->font, kCTFontOrientationDefault, &(m_impl->cur_glyph_index), &advances, 1); + m_impl->cur_advance_x = (scalar)advances.width; + m_impl->cur_advance_y = (scalar)advances.height; + + CGPathRef fontPath = CTFontCreatePathForGlyph(m_impl->font, m_impl->cur_glyph_index, &m_impl->matrix); + m_impl->cur_font_path.remove_all(); + CGPathApply(fontPath, m_impl, _cgPathReader); + m_impl->cur_bound_rect = get_bounding_rect(m_impl->cur_font_path); + m_impl->cur_data_size = m_impl->cur_font_path.total_byte_size()+sizeof(unsigned int);//count data + m_impl->ascent = (scalar)CTFontGetAscent(m_impl->font); + m_impl->descent = (scalar)CTFontGetDescent(m_impl->font); + m_impl->leading = (scalar)CTFontGetLeading(m_impl->font); + m_impl->units_per_em = CTFontGetUnitsPerEm(m_impl->font); + m_impl->height = m_impl->ascent + m_impl->descent; + CGPathRelease(fontPath); + return true; + } + return false; +} + +void gfx_font_adapter::write_glyph_to(byte* buffer) +{ + if (buffer && m_impl->cur_data_size) { + unsigned int count = m_impl->cur_font_path.total_vertices(); + mem_copy(buffer, &count, sizeof(unsigned int)); + buffer += sizeof(unsigned int); + m_impl->cur_font_path.serialize_to(buffer); + } +} + +scalar gfx_font_adapter::ascent(void) const +{ + return m_impl->ascent; +} + +scalar gfx_font_adapter::descent(void) const +{ + return m_impl->descent; +} + +scalar gfx_font_adapter::leading(void) const +{ + return m_impl->leading; +} + +unsigned int gfx_font_adapter::units_per_em(void) const +{ + return m_impl->units_per_em; +} + +unsigned int gfx_font_adapter::glyph_index(void) const +{ + return (unsigned int)m_impl->cur_glyph_index; +} + +unsigned int gfx_font_adapter::data_size(void) const +{ + return m_impl->cur_data_size; +} + +glyph_type gfx_font_adapter::data_type(void) const +{ + return glyph_type_outline; +} + +const rect& gfx_font_adapter::bounds(void) const +{ + return m_impl->cur_bound_rect; +} + +scalar gfx_font_adapter::height(void) const +{ + return m_impl->height; +} + +scalar gfx_font_adapter::advance_x(void) const +{ + return m_impl->cur_advance_x; +} + +scalar gfx_font_adapter::advance_y(void) const +{ + return m_impl->cur_advance_y; +} + +void gfx_font_adapter::add_kerning(unsigned int first, unsigned int second, scalar* x, scalar* y) +{ + //FIXME:implement +} + + +void gfx_font_adapter::active(void) { } +void gfx_font_adapter::deactive(void) { } +void* gfx_font_adapter::create_storage(byte* buf, unsigned int len, scalar x, scalar y) { return NULL; } +void gfx_font_adapter::destroy_storage(void*) { } +void gfx_font_adapter::translate_storage(void* storage, scalar x, scalar y) { } +} + +bool platform_font_init(void) { return true; } +void platform_font_shutdown(void) { } diff --git a/src/gfx/gfx_font_adapter_dummy.cpp b/src/gfx/gfx_font_adapter_dummy.cpp index 8c2287a..b5ae9bd 100644 --- a/src/gfx/gfx_font_adapter_dummy.cpp +++ b/src/gfx/gfx_font_adapter_dummy.cpp @@ -10,7 +10,7 @@ #include "gfx_font_adapter.h" #include "gfx_trans_affine.h" -#if !defined(WIN32) && !ENABLE(FREE_TYPE2) +#if !defined(WIN32) && !ENABLE(FREE_TYPE2) && !defined(__APPLE__) // dummy font interface namespace gfx { diff --git a/src/gfx/gfx_font_adapter_freetype2.cpp b/src/gfx/gfx_font_adapter_freetype2.cpp index a66fb87..7dc8491 100644 --- a/src/gfx/gfx_font_adapter_freetype2.cpp +++ b/src/gfx/gfx_font_adapter_freetype2.cpp @@ -48,7 +48,6 @@ class font_adapter_impl , cur_bound_rect(0,0,0,0) , cur_advance_x(0) , cur_advance_y(0) - { } diff --git a/src/picasso_api.cpp b/src/picasso_api.cpp index 9247707..879a51b 100644 --- a/src/picasso_api.cpp +++ b/src/picasso_api.cpp @@ -32,7 +32,7 @@ static inline void _clip_path(context_state* state, const graphic_path& p, filli } -#define PICASSO_VERSION 23020 // version 2.3.2 +#define PICASSO_VERSION 25000 // version 2.5.0 #ifdef __cplusplus extern "C" { diff --git a/src/src.gypi b/src/src.gypi index ac45609..cc3dd83 100644 --- a/src/src.gypi +++ b/src/src.gypi @@ -133,8 +133,14 @@ }], ['OS=="macosx" or OS=="ios"', { 'sources': [ - 'gfx/gfx_font_adapter_apple.m', + 'gfx/gfx_font_adapter_apple.mm', ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/CoreText.framework', + '$(SDKROOT)/System/Library/Frameworks/CoreGraphics.framework', + ], + }, }], ], 'includes':[ diff --git a/test/testGLES2.c b/test/testGLES2.c index b8a0d58..b359f1e 100644 --- a/test/testGLES2.c +++ b/test/testGLES2.c @@ -144,6 +144,10 @@ const char** argv(void) return __argv; } +const char* getSysFontName(void) { + return "sans-serif"; +} + int main(int argc, char*argv[]) { GLES2_CONTEXT ctx; diff --git a/test/testGtk2.c b/test/testGtk2.c index 4dabddb..23cb263 100644 --- a/test/testGtk2.c +++ b/test/testGtk2.c @@ -82,6 +82,10 @@ const char** argv(void) return __argv; } +const char* getSysFontName(void) { + return "sans-serif"; +} + int main(int argc, char* argv[]) { GtkWidget *window; diff --git a/test/testMac.m b/test/testMac.m index 9d02036..3aec3c5 100644 --- a/test/testMac.m +++ b/test/testMac.m @@ -112,6 +112,11 @@ int argc(void) return __argv; } + +const char* getSysFontName(void) { + return "STHeitiSC-Light"; +} + int main(int argc, const char * argv[]) { __argc = (int)argc; diff --git a/test/testQt4.cpp b/test/testQt4.cpp index 7a07bc2..20dae1b 100644 --- a/test/testQt4.cpp +++ b/test/testQt4.cpp @@ -90,6 +90,11 @@ extern "C" const char** argv(void) return __argv; } +extern "C" const char* getSysFontName(void) +{ + return "sans-serif"; +} + int main(int argc, char* argv[]) { __argc = argc; diff --git a/test/testWin.c b/test/testWin.c index 62370f8..aadcadd 100644 --- a/test/testWin.c +++ b/test/testWin.c @@ -44,6 +44,12 @@ const char** argv(void) return (const char**)__argv; } +const char* getSysFontName(void) +{ + return "Arial"; +} + + int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, diff --git a/test/text_func.c b/test/text_func.c index a2319f2..2e50449 100644 --- a/test/text_func.c +++ b/test/text_func.c @@ -18,6 +18,9 @@ const char* text = "Hello World! this is the first words picasso out put!"; const ps_uchar16 wtext[] = {0x77e2,0x91cf,0x56fe,0x5f62,0x5e93}; const char gtext[] = "ASDFG"; static int step = 0; + +extern const char* getSysFontName(void); + void draw_test (int id, ps_context* gc) { // int i; @@ -129,8 +132,7 @@ void init_context (ps_context* gc, ps_canvas* cs, unsigned char* buf) pm = ps_matrix_create(); pn = ps_matrix_create(); - pf = ps_font_create("sans-serif", CHARSET_UNICODE,48, FONT_WEIGHT_BOLD, False); - + pf = ps_font_create(getSysFontName(), CHARSET_UNICODE, 48, FONT_WEIGHT_BOLD, False); p[0].x = 150; p[0].y = 100;