From b8f20dfe493fa02fab87a3a2ff5fe37bdb94ff37 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 25 Jun 2014 14:16:16 -0700 Subject: [PATCH] Add a custom stream IO implementation for Freetype Freetype expects its IO to perform like mmap (i.e. seeking to be free), but the non-unix implementation uses fseek and fread. This implementation simply reads the entire file into a buffer, as fonts generally aren't very big. Cuts the time to recreate the fontconfig cache on my machine by about 60%. --- build/freetype2/freetype.vcxproj | 2 +- build/freetype2/freetype.vcxproj.filters | 2 +- build/freetype2/ftsystem.cpp | 75 ++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 build/freetype2/ftsystem.cpp diff --git a/build/freetype2/freetype.vcxproj b/build/freetype2/freetype.vcxproj index e74cd44a9..b90e2911e 100644 --- a/build/freetype2/freetype.vcxproj +++ b/build/freetype2/freetype.vcxproj @@ -36,6 +36,7 @@ + @@ -52,7 +53,6 @@ - diff --git a/build/freetype2/freetype.vcxproj.filters b/build/freetype2/freetype.vcxproj.filters index 89a2683a1..3c200ea5a 100644 --- a/build/freetype2/freetype.vcxproj.filters +++ b/build/freetype2/freetype.vcxproj.filters @@ -62,7 +62,7 @@ Source Files - + Source Files diff --git a/build/freetype2/ftsystem.cpp b/build/freetype2/ftsystem.cpp new file mode 100644 index 000000000..c380bb058 --- /dev/null +++ b/build/freetype2/ftsystem.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2014, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +// The non-unix version of ftsystem.c uses stdio functions, but freetype uses +// streams as if they had mmap's performance characteristics (as it uses mmap +// on unix), which results in mind-blowingly poor performance (35%+ of the +// fontconfig caching runtime is spent on fseek). + +#include +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_SYSTEM_H +#include FT_ERRORS_H + +#include +#include + +extern "C" FT_Error FT_Stream_Open(FT_Stream stream, const char *filepathname) { + if (!stream) + return FT_THROW(Invalid_Stream_Handle); + + stream->descriptor.pointer = nullptr; + stream->pathname.pointer = const_cast(filepathname); + stream->base = nullptr; + stream->pos = 0; + stream->read = nullptr; + stream->close = nullptr; + + std::wstring_convert, wchar_t> converter; + std::ifstream file(converter.from_bytes(filepathname), std::ios::binary); + if (!file.good()) + return FT_THROW(Cannot_Open_Resource); + + file.seekg(0, std::ios::end); + stream->size = (unsigned long)file.tellg(); + if (!stream->size) + return FT_THROW(Cannot_Open_Stream); + file.seekg(0, std::ios::beg); + + stream->base = (unsigned char *)malloc(stream->size); + file.read((char *)stream->base, stream->size); + + stream->close = [](FT_Stream stream) { + free(stream->base); + stream->size = 0; + stream->base = nullptr; + }; + + return FT_Err_Ok; +} + +extern "C" FT_Memory FT_New_Memory() { + return new FT_MemoryRec_{ + nullptr, + [](FT_Memory, long size) { return malloc(size); }, + [](FT_Memory, void *ptr) { free(ptr); }, + [](FT_Memory, long, long size, void *ptr) { return realloc(ptr, size); }}; +} + +extern "C" void FT_Done_Memory(FT_Memory memory) { + delete memory; +}