diff --git a/doc/doc_files/nav_bottom.html b/doc/doc_files/nav_bottom.html index bd64910..f703cf3 100644 --- a/doc/doc_files/nav_bottom.html +++ b/doc/doc_files/nav_bottom.html @@ -299,6 +299,10 @@ ul, #myUL {
  • Stack_Size_S
  • +
  • Stack_N_Exists
  • + +
  • Stack_S_Exists
  • + @@ -569,6 +573,18 @@ ul, #myUL {
  • GetSpriteCanvasRenderPriority
  • +
  • SetPostEffect
  • + +
  • ClearPostEffect
  • + +
  • SetPostEffectProperty
  • + +
  • GetPostEffectProperty
  • + +
  • SetPostEffectActive
  • + +
  • PostEffectIsActive
  • + @@ -1173,6 +1189,8 @@ ul, #myUL {
  • GetMatrixScale
  • +
  • MatrixExists
  • + @@ -1451,6 +1469,8 @@ ul, #myUL {
  • GetSpriteShapeOffset
  • +
  • GetSpriteWorldCenter
  • + @@ -1691,6 +1711,16 @@ ul, #myUL {
  • FlipMeshSurfaces
  • +
  • SetMeshBuffer
  • + +
  • GetMeshBufferCount
  • + +
  • GetMeshBufferVertexCount
  • + +
  • GetMeshBufferIndexCount
  • + +
  • GetMeshBuffer
  • + @@ -2233,6 +2263,12 @@ ul, #myUL {
  • GetSceneAmbientColor
  • +
  • Pipeline_Begin
  • + +
  • Pipeline_End
  • + +
  • Pipeline_Render
  • + diff --git a/rcbasic_build/rcbasic4_changes.ods b/rcbasic_build/rcbasic4_changes.ods index 4a19efc..ecabd31 100644 Binary files a/rcbasic_build/rcbasic4_changes.ods and b/rcbasic_build/rcbasic4_changes.ods differ diff --git a/rcbasic_runtime/Android.mk b/rcbasic_runtime/Android.mk old mode 100755 new mode 100644 index 81ef9e5..3c07759 --- a/rcbasic_runtime/Android.mk +++ b/rcbasic_runtime/Android.mk @@ -1,151 +1,85 @@ LOCAL_PATH := $(call my-dir) -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) -LOCAL_MODULE := Bullet-prebuilt -LOCAL_SRC_FILES := ../bullet3/build3/Android/obj/local/$(TARGET_ARCH_ABI)/libBullet.a -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. -include $(PREBUILT_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := freetype-prebuilt -LOCAL_SRC_FILES := ../freetype/Android/libs/$(TARGET_ARCH_ABI)/libfreetype.so -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/.. -include $(PREBUILT_SHARED_LIBRARY) - include $(CLEAR_VARS) LOCAL_MODULE := main SDL_PATH := ../SDL -SDL_IMAGE_PATH := ../SDL2_image -SDL_MIXER_PATH := ../SDL2_mixer -SDL_NET_PATH := ../SDL2_net +IRRLICHT_PATH := ../RCIrrlicht + +SDL_MIXER_PATH := ../SDL_mixer +SDL_NET_PATH := ../SDL_net THEORA_PATH := ../theora -IRR_PATH := ../RCIrrlicht -BULLET_PATH := ../bullet3 -IRRBULLET_PATH := ../irrBullet -IRRTHEORA_PATH := ../irrTheora -FREETYPE_PATH := ../freetype -BOX2D_PATH := ../box2d-2.4.2 +IRR_THEORA_PATH := ../irrTheora + AN8_PATH := ../an8-parser +BOX2D_PATH := ../box2d-2.4.2 +BULLET_PATH := ../bullet3 +IRR_BULLET_PATH := ../irrBullet + VORBIS_LIBRARY_PATH := ../libvorbis64 THEORAPLAY_PATH := ../src/theoraplay -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) -VORBIS_LIBRARY_PATH := ../libvorbisidec-1.2.1 -THEORAPLAY_PATH := ../src/theoraplay_tremor -endif +FREETYPE_PATH := ../freetype-2.9.1 -LOCAL_CFLAGS := -I$(LOCAL_PATH)/$(THEORAPLAY_PATH) -I$(LOCAL_PATH)/$(IRR_PATH)/include -DRC_ANDROID_BUILD -LOCAL_CPP_FEATURES += exceptions +LOCAL_CFLAGS := -I$(LOCAL_PATH)/$(THEORAPLAY_PATH) -DRC_ANDROID_BUILD LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include \ - $(LOCAL_PATH)/$(SDL_IMAGE_PATH) \ - $(LOCAL_PATH)/$(SDL_MIXER_PATH) \ - $(LOCAL_PATH)/$(SDL_NET_PATH) \ - $(LOCAL_PATH)/$(THEORA_PATH) \ + $(LOCAL_PATH)/$(SDL_MIXER_PATH)/include \ + $(LOCAL_PATH)/$(SDL_NET_PATH)/include \ + $(LOCAL_PATH)/$(THEORA_PATH)/include \ $(LOCAL_PATH)/$(VORBIS_LIBRARY_PATH)/include \ $(LOCAL_PATH)/$(THEORAPLAY_PATH) \ - $(LOCAL_PATH)/$(IRR_PATH)/include \ - $(LOCAL_PATH)/$(BULLET_PATH)/src \ - $(LOCAL_PATH)/$(IRRBULLET_PATH)/include \ - $(LOCAL_PATH)/$(IRRTHEORA_PATH) \ + $(LOCAL_PATH)/$(IRR_THEORA_PATH) \ $(LOCAL_PATH)/$(FREETYPE_PATH)/include \ $(LOCAL_PATH)/$(AN8_PATH) \ - $(LOCAL_PATH)/$(BOX2D_PATH)/include + $(LOCAL_PATH)/$(BOX2D_PATH)/include \ + $(LOCAL_PATH)/$(BULLET_PATH)/src \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/include + + +LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(IRRLICHT_PATH)/include # Add your application source files here... -LOCAL_SRC_FILES := main.cpp $(LOCAL_PATH)/$(THEORAPLAY_PATH)/theoraplay.c gui_freetype_font.cpp +LOCAL_SRC_FILES := main.cpp \ + CShader.cpp \ + gui_freetype_font.cpp \ + ProjectiveTextures.cpp \ + theoraplay.c -LOCAL_SRC_FILES += \ - $(BOX2D_PATH)/src/collision/b2_broad_phase.cpp \ - $(BOX2D_PATH)/src/collision/b2_chain_shape.cpp \ - $(BOX2D_PATH)/src/collision/b2_circle_shape.cpp \ - $(BOX2D_PATH)/src/collision/b2_collide_circle.cpp \ - $(BOX2D_PATH)/src/collision/b2_collide_edge.cpp \ - $(BOX2D_PATH)/src/collision/b2_collide_polygon.cpp \ - $(BOX2D_PATH)/src/collision/b2_collision.cpp \ - $(BOX2D_PATH)/src/collision/b2_distance.cpp \ - $(BOX2D_PATH)/src/collision/b2_dynamic_tree.cpp \ - $(BOX2D_PATH)/src/collision/b2_edge_shape.cpp \ - $(BOX2D_PATH)/src/collision/b2_polygon_shape.cpp \ - $(BOX2D_PATH)/src/collision/b2_time_of_impact.cpp \ - $(BOX2D_PATH)/src/common/b2_block_allocator.cpp \ - $(BOX2D_PATH)/src/common/b2_draw.cpp \ - $(BOX2D_PATH)/src/common/b2_math.cpp \ - $(BOX2D_PATH)/src/common/b2_settings.cpp \ - $(BOX2D_PATH)/src/common/b2_stack_allocator.cpp \ - $(BOX2D_PATH)/src/common/b2_timer.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_body.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_chain_circle_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_chain_polygon_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_circle_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_contact_manager.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_contact_solver.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_distance_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_edge_circle_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_edge_polygon_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_fixture.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_friction_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_gear_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_island.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_motor_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_mouse_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_polygon_circle_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_polygon_contact.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_prismatic_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_pulley_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_revolute_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_weld_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_wheel_joint.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_world_callbacks.cpp \ - $(BOX2D_PATH)/src/dynamics/b2_world.cpp \ - $(BOX2D_PATH)/src/rope/b2_rope.cpp \ - $(IRRBULLET_PATH)/src/irrBulletBoxShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletBvhTriangleMeshShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCapsuleShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionCallBackInformation.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffectorAttract.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffector.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionObjectAffectorDelete.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionObject.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCollisionShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletcommon.cpp \ - $(IRRBULLET_PATH)/src/irrBulletConeShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletConvexHullShape.cpp \ - $(IRRBULLET_PATH)/src/irrBullet.cpp \ - $(IRRBULLET_PATH)/src/irrBulletCylinderShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletGhostObject.cpp \ - $(IRRBULLET_PATH)/src/irrBulletGImpactMeshShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletLiquidBody.cpp \ - $(IRRBULLET_PATH)/src/irrBulletMotionState.cpp \ - $(IRRBULLET_PATH)/src/irrBulletPhysicsDebug.cpp \ - $(IRRBULLET_PATH)/src/irrBulletRayCastVehicle.cpp \ - $(IRRBULLET_PATH)/src/irrBulletRigidBody.cpp \ - $(IRRBULLET_PATH)/src/irrBulletSoftBody.cpp \ - $(IRRBULLET_PATH)/src/irrBulletSphereShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletTriangleMeshShape.cpp \ - $(IRRBULLET_PATH)/src/irrBulletWorld.cpp +# Add irrBullet source files +LOCAL_SRC_FILES += $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletBoxShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletBvhTriangleMeshShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCapsuleShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionCallBackInformation.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffectorAttract.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffector.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObjectAffectorDelete.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionObject.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCollisionShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletcommon.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletConeShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletConvexHullShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBullet.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletCylinderShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletGhostObject.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletGImpactMeshShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletLiquidBody.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletMotionState.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletPhysicsDebug.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletRayCastVehicle.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletRigidBody.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletSoftBody.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletSphereShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletTriangleMeshShape.cpp \ + $(LOCAL_PATH)/$(IRR_BULLET_PATH)/src/irrBulletWorld.cpp +# LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_net ogg_shared vorbis64 theora +LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_net SDL2_ttf ogg_shared vorbis64 theora +LOCAL_STATIC_LIBRARIES := Irrlicht Box2d Bullet freetype - -LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_mixer SDL2_net Irrlicht freetype-prebuilt -LOCAL_STATIC_LIBRARIES := Bullet-prebuilt android_native_app_glue - -RC_TH_LOCAL_SHARED_LIBRARIES := ogg_shared vorbis64 theora - -ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) -RC_TH_LOCAL_SHARED_LIBRARIES := ogg_shared tremor theora -LOCAL_CFLAGS += -DRC_USE_TREMOR -O2 -endif - -LOCAL_SHARED_LIBRARIES += $(RC_TH_LOCAL_SHARED_LIBRARIES) - -LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid include $(BUILD_SHARED_LIBRARY) diff --git a/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp b/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp new file mode 100755 index 0000000..e2707b6 --- /dev/null +++ b/rcbasic_runtime/android_alt_src/gui_freetype_font.cpp @@ -0,0 +1,616 @@ +#include "gui_freetype_font.h" + +#include + +#if COMPILE_WITH_FREETYPE + +#include + +#include + +#define LOGE(TAG, ...) __android_log_print(ANDROID_LOG_ERROR , TAG,__VA_ARGS__) + +using namespace irr; +using namespace gui; + +#ifdef _MSC_VER +#pragma warning(disable: 4996) +#endif + + +// -------------------------------------------------------- +CGUITTGlyph::CGUITTGlyph() +: IReferenceCounted() + ,cached(false) + ,size(0) + ,top(0) + ,left(0) + ,texw(0) + ,texh(0) + ,imgw(0) + ,imgh(0) + ,tex(NULL) + ,top16(0) + ,left16(0) + ,texw16(0) + ,texh16(0) + ,imgw16(0) + ,imgh16(0) + ,tex16(NULL) + ,image(NULL) +{ +} + +CGUITTGlyph::~CGUITTGlyph() +{ + delete[] image; +} + +//void CGUITTGlyph::cache(u32 idx_, CGUITTFace& ttFace_, video::IVideoDriver* driver_, irr::core::dimension2d &largestSize) +void CGUITTGlyph::cache(u32 idx_, const CGUIFreetypeFont * freetypeFont) +{ + assert(freetypeFont); + + FT_Face face = freetypeFont->TrueTypeFace->face; + + FT_Set_Pixel_Sizes(face, 0, size); + if ( size > freetypeFont->LargestGlyph.Height ) + freetypeFont->LargestGlyph.Height = size; + + if ( !FT_Load_Glyph(face, idx_, FT_LOAD_NO_HINTING|FT_LOAD_NO_BITMAP) ) + { + FT_GlyphSlot glyph = face->glyph; + FT_Bitmap bits; + + if (glyph->format == ft_glyph_format_outline ) + { + if (!FT_Render_Glyph( glyph, FT_RENDER_MODE_NORMAL)) + { + bits = glyph->bitmap; + u8 *pt = bits.buffer; + delete[] image; + image = new u8[bits.width * bits.rows]; + memcpy(image,pt,bits.width * bits.rows); + top = glyph->bitmap_top; + left = glyph->bitmap_left; + imgw = 1; + imgh = 1; + texw = bits.width; + texh = bits.rows; + for(;;) + { + if (imgw > texw) + { + break; + } + else + { + imgw <<= 1; + } + } + for(;;) + { + if (imgh > texh) + { + break; + } + else + { + imgh <<= 1; + } + } + if (imgw > imgh) + { + imgh = imgw; + } + else + { + imgw = imgh; + } + + s32 offx = left; + s32 offy = size - top; + if ( offx+texw > freetypeFont->LargestGlyph.Width ) + freetypeFont->LargestGlyph.Width = offx+texw; + if ( offy+texh > freetypeFont->LargestGlyph.Height ) + freetypeFont->LargestGlyph.Height = offy+texh; + + u32 *texd = new u32[imgw*imgh]; + memset(texd,0,imgw*imgh*sizeof(u32)); + u32 *texp = texd; + bool cflag = (freetypeFont->Driver->getDriverType() == video::EDT_DIRECT3D9); + for (int i = 0;i < bits.rows;i++) + { + u32 *rowp = texp; + for (int j = 0;j < bits.width;j++) + { + if (*pt) + { + if (cflag) + { + *rowp = *pt; + *rowp *= 0x01010101; + } + else + { + *rowp = *pt << 24; + *rowp |= 0xffffff; + } + } + else + { + *rowp = 0; + } + pt++; + rowp++; + } + texp += imgw; + } + + c8 name[128]; + sprintf(name,"ttf%d_%d_%p",idx_, size, freetypeFont ); + video::IImage *img = freetypeFont->Driver->createImageFromData(video::ECF_A8R8G8B8,core::dimension2d(imgw,imgh),texd); + setGlyphTextureFlags(freetypeFont->Driver); + tex = freetypeFont->Driver->addTexture(name,img); + img->drop(); + restoreTextureFlags(freetypeFont->Driver); + delete[] texd; + cached = true; + } + } + } + + if (!FT_Load_Glyph(face,idx_,FT_LOAD_NO_HINTING|FT_LOAD_RENDER|FT_LOAD_MONOCHROME)) + { + FT_GlyphSlot glyph = face->glyph; + FT_Bitmap bits = glyph->bitmap; + u8 *pt = bits.buffer; + top16 = glyph->bitmap_top; + left16 = glyph->bitmap_left; + imgw16 = 1; + imgh16 = 1; + texw16 = bits.width; + texh16 = bits.rows; + for(;;) + { + if (imgw16 >= texw16) + { + break; + } + else + { + imgw16 <<= 1; + } + } + for(;;) + { + if (imgh16 >= texh16) + { + break; + } + else + { + imgh16 <<= 1; + } + } + if (imgw16 > imgh16) + { + imgh16 = imgw16; + } + else + { + imgw16 = imgh16; + } + + s32 offx = left; + s32 offy = size - top; + if ( offx+texw > freetypeFont->LargestGlyph.Width ) + freetypeFont->LargestGlyph.Width = offx+texw; + if ( offy+texh > freetypeFont->LargestGlyph.Height ) + freetypeFont->LargestGlyph.Height = offy+texh; + + + u16 *texd16 = new u16[imgw16*imgh16]; + memset(texd16,0,imgw16*imgh16*sizeof(u16)); + u16 *texp16 = texd16; + for (int y = 0;y < bits.rows;y++) + { + u16 *rowp = texp16; + for (int x = 0;x < bits.width;x++) + { + if (pt[y * bits.pitch + (x / 8)] & (0x80 >> (x % 8))) + { + *rowp = 0xffff; + } + rowp++; + } + texp16 += imgw16; + } + c8 name[128]; + sprintf(name,"ttf%d_%d_%p_16",idx_, size, freetypeFont ); + video::IImage *img = freetypeFont->Driver->createImageFromData(video::ECF_A1R5G5B5,core::dimension2d(imgw16,imgh16),texd16); + setGlyphTextureFlags(freetypeFont->Driver); + tex16 = freetypeFont->Driver->addTexture(name,img); + img->drop(); + restoreTextureFlags(freetypeFont->Driver); +// freetypeFont->Driver->makeColorKeyTexture(tex16,video::SColor(0,0,0,0)); + delete[] texd16; + } +} + +bool CGUITTGlyph::mTexFlag16 = false; +bool CGUITTGlyph::mTexFlag32 = true; +bool CGUITTGlyph::mTexFlagMip = false; + +void CGUITTGlyph::setGlyphTextureFlags(video::IVideoDriver* driver_) +{ + mTexFlag16 = driver_->getTextureCreationFlag(video::ETCF_ALWAYS_16_BIT); + mTexFlag32 = driver_->getTextureCreationFlag(video::ETCF_ALWAYS_32_BIT); + mTexFlagMip = driver_->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); + driver_->setTextureCreationFlag(video::ETCF_ALWAYS_16_BIT,false); + driver_->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT,true); + driver_->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); +} + +void CGUITTGlyph::restoreTextureFlags(video::IVideoDriver* driver_) +{ + driver_->setTextureCreationFlag(video::ETCF_ALWAYS_16_BIT, mTexFlag16); + driver_->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, mTexFlag32); + driver_->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mTexFlagMip); +} + +// -------------------------------------------------------- +FT_Library CGUITTFace::library = 0; +int CGUITTFace::countClassObjects = 0; +bool CGUITTFace::ttf_init = false; + +CGUITTFace::CGUITTFace() +: face(0) +{ + ++countClassObjects; + is_sdl = false; + + if(!ttf_init) + { + TTF_Init(); + ttf_init = true; + } +} + +CGUITTFace::~CGUITTFace() +{ + if( is_sdl ) + { + TTF_CloseFont(sdl_font); + face = NULL; + sdl_font = NULL; + } + + if ( face ) + FT_Done_Face( face ); + + --countClassObjects; + assert(countClassObjects >= 0 ); + if ( !countClassObjects && library ) + { + FT_Done_FreeType( library ); + library = 0; + } +} + +//! loads a font file +bool CGUITTFace::load(const irr::io::path& filename) +{ + //TTF_Font* sdl_font = TTF_Open + if ( !library ) + { + if (FT_Init_FreeType( &library )) + { + return false; + } + } + core::stringc ansiFilename(filename); // path can be anything but freetype can only work with ansi-filenames + if (FT_New_Face( library,ansiFilename.c_str(),0,&face )) + { + return false; + } + return true; +} + +// -------------------------------------------------------- +//! constructor +CGUIFreetypeFont::CGUIFreetypeFont(video::IVideoDriver* driver) +: Driver(driver) +, TrueTypeFace(0) +{ + #ifdef _DEBUG + setDebugName("CGUIFreetypeFont"); + #endif + + if (Driver) + Driver->grab(); + AntiAlias = false; + Transparency = false; +} + + + +//! destructor +CGUIFreetypeFont::~CGUIFreetypeFont() +{ + if ( TrueTypeFace ) + TrueTypeFace->drop(); + if (Driver) + Driver->drop(); + clearGlyphs(); +} + +bool CGUIFreetypeFont::attach(CGUITTFace *Face,u32 size) +{ + if (!Driver || !Face) + return false; + + Face->grab(); + if ( TrueTypeFace ) + TrueTypeFace->drop(); + TrueTypeFace = Face; + if ( !TrueTypeFace ) + return false; + + clearGlyphs(); + Glyphs.reallocate(TrueTypeFace->face->num_glyphs); + Glyphs.set_used(TrueTypeFace->face->num_glyphs); + for (int i = 0;i < TrueTypeFace->face->num_glyphs;i++) + { + CGUITTGlyph * glyph = new CGUITTGlyph(); + + glyph->size = size; +// glyph->cache((wchar_t)i + 1); + + Glyphs[i] = glyph; + } + + // TODO: this is a workaround to get a probably ok height for getDimensions. So we check a few extreme characters which usually make trouble. + getGlyphByChar(L'A'); + getGlyphByChar(L'g'); + getGlyphByChar(L'.'); + getGlyphByChar(L'('); + + return true; +} + +bool CGUIFreetypeFont::sdl_loadfont(irr::io::path font_file,irr::u32 size) +{ + if (!Driver) + return false; + + CGUITTFace *Face = new CGUITTFace(); + + if(!Face) + return false; + + TTF_Font* sdl_font = TTF_OpenFont(font_file.c_str(), size); + + if(!sdl_font) + { + LOGE("RCTEST", "TTF_OpenFont(%s) FAILED -> error: %s", font_file.c_str(), TTF_GetError()); + delete Face; + return false; + } + + Face->face = (FT_Face)TTF_GetFreeTypeFace(sdl_font); + Face->is_sdl = true; + + Face->grab(); + if ( TrueTypeFace ) + TrueTypeFace->drop(); + TrueTypeFace = Face; + if ( !TrueTypeFace ) + return false; + + clearGlyphs(); + Glyphs.reallocate(TrueTypeFace->face->num_glyphs); + Glyphs.set_used(TrueTypeFace->face->num_glyphs); + for (int i = 0;i < TrueTypeFace->face->num_glyphs;i++) + { + CGUITTGlyph * glyph = new CGUITTGlyph(); + + glyph->size = size; +// glyph->cache((wchar_t)i + 1); + + Glyphs[i] = glyph; + } + + // TODO: this is a workaround to get a probably ok height for getDimensions. So we check a few extreme characters which usually make trouble. + getGlyphByChar(L'A'); + getGlyphByChar(L'g'); + getGlyphByChar(L'.'); + getGlyphByChar(L'('); + + return true; +} + +CGUITTFace* CGUIFreetypeFont::getFace() +{ + return TrueTypeFace; +} + +void CGUIFreetypeFont::clearGlyphs() +{ + for ( unsigned int i=0; i < Glyphs.size(); ++i ) + { + if ( Glyphs[i] ) + { + Glyphs[i]->drop(); + } + Glyphs[i] = 0; + } +} + +u32 CGUIFreetypeFont::getGlyphByChar(wchar_t c) const +{ + u32 idx = FT_Get_Char_Index( TrueTypeFace->face, c ); + if ( idx && !Glyphs[idx - 1]->cached ) + Glyphs[idx - 1]->cache(idx, this); + return idx; +} + +//! returns the dimension of a text +core::dimension2d CGUIFreetypeFont::getDimension(const wchar_t* text) const +{ + core::dimension2d dim(0, Glyphs[0]->size); + + for(const wchar_t* p = text; *p; ++p) + { + dim.Width += getWidthFromCharacter(*p); + } + + // TODO: The correct solution might be working with TrueTypeFace->height but I can't figure out how to use units_per_EM + // even if I know which FT_Render_Mode I used. I'm sure there is some way to figure that out, but I have to give up for now. + if ( TrueTypeFace && LargestGlyph.Height > dim.Height) + dim.Height = LargestGlyph.Height; + + return dim; +} + + +inline u32 CGUIFreetypeFont::getWidthFromCharacter(wchar_t c) const +{ + u32 n = getGlyphByChar(c); + if ( n > 0) + { + int w = Glyphs[n - 1]->texw; + s32 left = Glyphs[n - 1]->left; + if (w + left > 0) + return w + left; + } + if (c >= 0x2000) + { + return Glyphs[0]->size; + } + else + { + return Glyphs[0]->size / 2; + } +} + + +//! draws an text and clips it to the specified rectangle if wanted +void CGUIFreetypeFont::draw(const irr::core::stringw& textstring, const irr::core::rect& position, video::SColor color, bool hcenter, bool vcenter, const core::rect* clip) +{ + if (!Driver) + return; + + core::dimension2d textDimension; + core::position2d offset = position.UpperLeftCorner; + video::SColor colors[4]; + for (int i = 0;i < 4;i++) + { + colors[i] = color; + } + + const wchar_t * text = textstring.c_str(); + if (hcenter || vcenter) + { + textDimension = getDimension(text); + + if (hcenter) + offset.X = ((position.getWidth() - textDimension.Width)>>1) + offset.X; + + if (vcenter) + offset.Y = ((position.getHeight() - textDimension.Height)>>1) + offset.Y; + } + + u32 n; + + while(*text) + { + n = getGlyphByChar(*text); + if ( n > 0) + { + if (AntiAlias) + { +// s32 imgw = Glyphs[n-1]->imgw; +// s32 imgh = Glyphs[n-1]->imgh; + s32 texw = Glyphs[n-1]->texw; + s32 texh = Glyphs[n-1]->texh; + s32 offx = Glyphs[n-1]->left; + s32 offy = Glyphs[n-1]->size - Glyphs[n-1]->top; + if (Driver->getDriverType() != video::EDT_SOFTWARE) + { + if (!Transparency) + color.color |= 0xff000000; + Driver->draw2DImage(Glyphs[n-1]->tex,core::position2d(offset.X+offx,offset.Y+offy),core::rect(0,0,texw,texh),clip,color,true); + } + else + { + s32 a = color.getAlpha(); + s32 r = color.getRed(); + s32 g = color.getGreen(); + s32 b = color.getBlue(); + u8 *pt = Glyphs[n-1]->image; + if (!Transparency) a = 255; + for (int y = 0;y < texh;y++) + { + for (int x = 0;x < texw;x++) + { + if (!clip || clip->isPointInside(core::position2d(offset.X+x+offx,offset.Y+y+offy))) + { + if (*pt) + { + Driver->draw2DRectangle(video::SColor((a * *pt)/255,r,g,b),core::rect(offset.X+x+offx,offset.Y+y+offy,offset.X+x+offx+1,offset.Y+y+offy+1)); + } + pt++; + } + } + } + } + } + else + { +// s32 imgw = Glyphs[n-1]->imgw16; +// s32 imgh = Glyphs[n-1]->imgh16; + s32 texw = Glyphs[n-1]->texw16; + s32 texh = Glyphs[n-1]->texh16; + s32 offx = Glyphs[n-1]->left16; + s32 offy = Glyphs[n-1]->size - Glyphs[n-1]->top16; + if (!Transparency) + { + color.color |= 0xff000000; + } + Driver->draw2DImage(Glyphs[n-1]->tex16, + core::position2d(offset.X+offx,offset.Y+offy), + core::rect(0,0,texw,texh), + clip, color, true); + } + offset.X += getWidthFromCharacter(*text); + } + else + { + offset.X += getWidthFromCharacter(*text); + } + + ++text; + } +} + +//! Calculates the index of the character in the text which is on a specific position. +s32 CGUIFreetypeFont::getCharacterFromPos(const wchar_t* text, s32 pixel_x) const +{ + s32 x = 0; + s32 idx = 0; + + while (text[idx]) + { + x += getWidthFromCharacter(text[idx]); + + if (x >= pixel_x) + return idx; + + ++idx; + } + + return -1; +} + +#endif // #if COMPILE_WITH_FREETYPE diff --git a/rcbasic_runtime/android_alt_src/gui_freetype_font.h b/rcbasic_runtime/android_alt_src/gui_freetype_font.h new file mode 100755 index 0000000..2e6a65e --- /dev/null +++ b/rcbasic_runtime/android_alt_src/gui_freetype_font.h @@ -0,0 +1,141 @@ +#include "rc_os_defines.h" + +#ifndef _GUI_FREETYPE_FONT_H +#define _GUI_FREETYPE_FONT_H + +//! freetype support enabled with 1 and disabled with 0 +#define COMPILE_WITH_FREETYPE 1 + + +#if COMPILE_WITH_FREETYPE + +#ifdef RC_ANDROID + #include "ft2build.h" + #include "freetype/freetype.h" + #include +#else + #include + #include +#endif // RC_ANDROID +#include + +class CGUITTFace : public irr::IReferenceCounted +{ +public: + CGUITTFace(); + virtual ~CGUITTFace(); + + bool load(const irr::io::path& filename); + + FT_Face face; // handle to face + bool is_sdl; + +private: + static bool ttf_init; + static int countClassObjects; + static FT_Library library; // handle to library + + TTF_Font* sdl_font; +}; + +class CGUIFreetypeFont; + +class CGUITTGlyph : public irr::IReferenceCounted +{ +public: + CGUITTGlyph(); + virtual ~CGUITTGlyph(); + + bool cached; + void cache(irr::u32 idx_, const CGUIFreetypeFont * freetypeFont); + + irr::u32 size; + irr::u32 top; + irr::u32 left; + irr::u32 texw; + irr::u32 texh; + irr::u32 imgw; + irr::u32 imgh; + irr::video::ITexture *tex; + irr::u32 top16; + irr::u32 left16; + irr::u32 texw16; + irr::u32 texh16; + irr::u32 imgw16; + irr::u32 imgh16; + irr::video::ITexture *tex16; + irr::u8 *image; + +private: + void setGlyphTextureFlags(irr::video::IVideoDriver* driver_); + void restoreTextureFlags(irr::video::IVideoDriver* driver_); + + static bool mTexFlag16; + static bool mTexFlag32; + static bool mTexFlagMip; +}; + +class CGUIFreetypeFont : public irr::gui::IGUIFont +{ + friend class CGUITTGlyph; + +public: + + //! constructor + CGUIFreetypeFont(irr::video::IVideoDriver* Driver); + + //! destructor + virtual ~CGUIFreetypeFont(); + + //! loads a truetype font file + bool attach(CGUITTFace *Face,irr::u32 size); + + //! loads a truetype font file using SDL2 + bool sdl_loadfont(irr::io::path font_file,irr::u32 size); + + CGUITTFace* getFace(); + + //! draws an text and clips it to the specified rectangle if wanted + virtual void draw(const irr::core::stringw& text, const irr::core::rect& position, irr::video::SColor color, bool hcenter=false, bool vcenter=false, const irr::core::rect* clip=0); + + //! returns the dimension of a text + virtual irr::core::dimension2d getDimension(const wchar_t* text) const; + + //! Calculates the index of the character in the text which is on a specific position. + virtual irr::s32 getCharacterFromPos(const wchar_t* text, irr::s32 pixel_x) const; + + //! Not yet supported + virtual void setKerningWidth (irr::s32 kerning) {} + + //! Not yet supported + virtual void setKerningHeight (irr::s32 kerning) {} + + //! Not yet supported + virtual irr::s32 getKerningWidth(const wchar_t* thisLetter=0, const wchar_t* previousLetter=0) const { return 0; } + + //! Not yet supported + virtual irr::s32 getKerningHeight() const { return 0; } + + //! Not yet supported + virtual void setInvisibleCharacters( const wchar_t *s ) {} + + + bool AntiAlias; + bool Transparency; + +protected: + void clearGlyphs(); + +private: + irr::u32 getWidthFromCharacter(wchar_t c) const; + irr::u32 getGlyphByChar(wchar_t c) const; + irr::video::IVideoDriver* Driver; + irr::core::array< CGUITTGlyph* > Glyphs; + CGUITTFace * TrueTypeFace; + mutable irr::core::dimension2d LargestGlyph; +}; + +#endif // #if COMPILE_WITH_FREETYPE + +#endif // _GUI_FREETYPE_FONT_H +