Wrap the library into a single header + CPP file pair

This commit is contained in:
Chlumsky 2023-07-12 18:35:31 +02:00
parent ef8070786c
commit 321a7a9732
5 changed files with 261 additions and 0 deletions

3
all-in-one/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
msdfgen.h
msdfgen.cpp
build/

63
all-in-one/CMakeLists.txt Normal file
View File

@ -0,0 +1,63 @@
cmake_minimum_required(VERSION 3.15)
option(MSDFGEN_USE_VCPKG "Use vcpkg package manager to link project dependencies" ON)
option(MSDFGEN_USE_FREETYPE "Build with the FreeType library" ON)
if(MSDFGEN_USE_VCPKG AND MSDFGEN_USE_FREETYPE)
# Make sure that vcpkg toolchain file is set
if(NOT CMAKE_TOOLCHAIN_FILE)
if(DEFINED ENV{VCPKG_ROOT})
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
else()
message(SEND_ERROR "Vcpkg toolchain not configured. Either set VCPKG_ROOT environment variable or pass -DCMAKE_TOOLCHAIN_FILE=VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake to cmake")
endif()
endif()
# Default to statically linked vcpkg triplet on Windows
if(WIN32 AND NOT VCPKG_TARGET_TRIPLET AND NOT MSDFGEN_DYNAMIC_RUNTIME)
if(CMAKE_GENERATOR_PLATFORM MATCHES "64$" AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
set(VCPKG_TARGET_TRIPLET "x64-windows-static")
elseif(CMAKE_GENERATOR_PLATFORM MATCHES "32$" OR CMAKE_GENERATOR_PLATFORM STREQUAL "x86")
set(VCPKG_TARGET_TRIPLET "x86-windows-static")
else()
if(CMAKE_GENERATOR_PLATFORM)
message(WARNING "Vcpkg triplet not explicitly specified and could not be deduced. Recommend using -DVCPKG_TARGET_TRIPLET=x64-windows-static or similar")
else()
message(WARNING "Vcpkg triplet not explicitly specified and could not be deduced. Recommend using -A to explicitly select platform (Win32 or x64)")
endif()
endif()
endif()
endif()
project(msdfgen LANGUAGES CXX)
if(MAX_WARNING_LEVEL)
if (MSVC)
add_compile_options(/W4)
else()
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
endif()
find_package(Python3 REQUIRED COMPONENTS Interpreter)
if(MSDFGEN_USE_FREETYPE AND NOT TARGET Freetype::Freetype)
find_package(Freetype REQUIRED)
endif()
execute_process(COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/generate.py")
add_library(msdfgen "${CMAKE_CURRENT_SOURCE_DIR}/msdfgen.h" "${CMAKE_CURRENT_SOURCE_DIR}/msdfgen.cpp")
set_property(TARGET msdfgen PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_compile_features(msdfgen PUBLIC cxx_std_11)
if(MSDFGEN_USE_FREETYPE)
target_compile_definitions(msdfgen PUBLIC MSDFGEN_USE_FREETYPE)
target_link_libraries(msdfgen PRIVATE Freetype::Freetype)
endif()
add_executable(msdfgen-test "${CMAKE_CURRENT_SOURCE_DIR}/test.cpp")
set_property(TARGET msdfgen-test PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_link_libraries(msdfgen-test PRIVATE msdfgen)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT msdfgen-test)
if(MSDFGEN_USE_FREETYPE)
target_link_libraries(msdfgen-test PRIVATE Freetype::Freetype)
endif()

135
all-in-one/generate.py Normal file
View File

@ -0,0 +1,135 @@
#!/usr/bin/env python3
import os
import re
rootDir = os.path.join(os.path.dirname(__file__), '..')
sourceList = [
'core/arithmetics.hpp',
'core/equation-solver.h',
'core/equation-solver.cpp',
'core/Vector2.h',
'core/Vector2.cpp',
'core/pixel-conversion.hpp',
'core/BitmapRef.hpp',
'core/Bitmap.h',
'core/Bitmap.hpp',
'core/Projection.h',
'core/Projection.cpp',
'core/SignedDistance.h',
'core/SignedDistance.cpp',
'core/Scanline.h',
'core/Scanline.cpp',
'core/EdgeColor.h',
'core/edge-segments.h',
'core/edge-segments.cpp',
'core/EdgeHolder.h',
'core/EdgeHolder.cpp',
'core/Contour.h',
'core/Contour.cpp',
'core/Shape.h',
'core/Shape.cpp',
'core/bitmap-interpolation.hpp',
'core/edge-coloring.h',
'core/edge-coloring.cpp',
'core/edge-selectors.h',
'core/edge-selectors.cpp',
'core/contour-combiners.h',
'core/contour-combiners.cpp',
'core/ShapeDistanceFinder.h',
'core/ShapeDistanceFinder.hpp',
'core/generator-config.h',
'core/msdf-error-correction.h',
'core/msdf-error-correction.cpp',
'core/MSDFErrorCorrection.h',
'core/MSDFErrorCorrection.cpp',
'core/msdfgen.cpp',
'ext/import-font.h',
'ext/import-font.cpp',
'ext/resolve-shape-geometry.h',
'ext/resolve-shape-geometry.cpp',
'msdfgen.h'
]
header = """
#pragma once
#ifndef _USE_MATH_DEFINES
#define _USE_MATH_DEFINES
#endif
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
"""
source = """
#include "msdfgen.h"
#include <algorithm>
#include <queue>
#ifdef MSDFGEN_USE_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_OUTLINE_H
#ifndef MSDFGEN_DISABLE_VARIABLE_FONTS
#include FT_MULTIPLE_MASTERS_H
#endif
#endif
"""
with open(os.path.join(rootDir, 'LICENSE.txt'), 'r') as file:
license = file.read()
license = '\n'.join([' * '+line for line in license.strip().split('\n')])
for filename in sourceList:
with open(os.path.join(rootDir, *filename.split('/')), 'r') as file:
src = file.read()
src = '\n'.join([line for line in src.split('\n') if not re.match(r'^\s*#(include\s.*|pragma\s+once)\s*$', line)])
if filename.startswith('ext/import-font.'):
src = '#ifdef MSDFGEN_USE_FREETYPE\n\n'+src+'\n\n#endif\n\n'
if filename.endswith('.h') or filename.endswith('.hpp'):
header += '\n\n'+src
if filename.endswith('.cpp'):
source += '\n\n'+src
header = '\n'+re.sub(r'\n{3,}', '\n\n', re.sub(r'}\s*namespace\s+msdfgen\s*{', '', re.sub(r'\/\*[^\*].*?\*\/', '', header, flags=re.DOTALL))).strip()+'\n'
source = '\n'+re.sub(r'\n{3,}', '\n\n', re.sub(r'}\s*namespace\s+msdfgen\s*{', '', re.sub(r'\/\*[^\*].*?\*\/', '', source, flags=re.DOTALL))).strip()+'\n'
header = """
/*
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR
* ---------------------------------------------
* A utility by Viktor Chlumsky, (c) 2014 - 2023
* https://github.com/Chlumsky/msdfgen
* Published under the MIT license
*
* The technique used to generate multi-channel distance fields in this code
* was developed by Viktor Chlumsky in 2014 for his master's thesis,
* "Shape Decomposition for Multi-Channel Distance Fields". It provides improved
* quality of sharp corners in glyphs and other 2D shapes compared to monochrome
* distance fields. To reconstruct an image of the shape, apply the median of three
* operation on the triplet of sampled signed distance values.
*
*/
"""+header
source = """
/*
* MULTI-CHANNEL SIGNED DISTANCE FIELD GENERATOR
* ---------------------------------------------
* https://github.com/Chlumsky/msdfgen
*
"""+license+"""
*
*/
"""+source
with open(os.path.join(os.path.dirname(__file__), 'msdfgen.h'), 'w') as file:
file.write(header)
with open(os.path.join(os.path.dirname(__file__), 'msdfgen.cpp'), 'w') as file:
file.write(source)

52
all-in-one/test.cpp Normal file
View File

@ -0,0 +1,52 @@
#include <cstdio>
#include "msdfgen.h"
using namespace msdfgen;
static bool saveRGBA(const char *filename, const BitmapConstRef<float, 4> &bitmap) {
if (FILE *f = fopen(filename, "wb")) {
char header[12];
header[0] = 'R', header[1] = 'G', header[2] = 'B', header[3] = 'A';
header[4] = char(bitmap.width>>24);
header[5] = char(bitmap.width>>16);
header[6] = char(bitmap.width>>8);
header[7] = char(bitmap.width);
header[8] = char(bitmap.height>>24);
header[9] = char(bitmap.height>>16);
header[10] = char(bitmap.height>>8);
header[11] = char(bitmap.height);
fwrite(header, 1, 12, f);
Bitmap<byte, 4> byteBitmap(bitmap.width, bitmap.height);
byte *d = (byte *) byteBitmap;
for (const float *s = bitmap.pixels, *end = bitmap.pixels+4*bitmap.width*bitmap.height; s < end; ++d, ++s)
*d = pixelFloatToByte(*s);
fwrite((const byte *) byteBitmap, 1, 4*bitmap.width*bitmap.height, f);
fclose(f);
return true;
}
return false;
}
int main() {
#ifdef MSDFGEN_USE_FREETYPE
bool success = false;
if (FreetypeHandle *ft = initializeFreetype()) {
if (FontHandle *font = loadFont(ft, "C:\\Windows\\Fonts\\arialbd.ttf")) {
Shape shape;
if (loadGlyph(shape, font, 'A')) {
shape.normalize();
edgeColoringByDistance(shape, 3.0);
Bitmap<float, 4> msdf(32, 32);
generateMTSDF(msdf, shape, 4.0, 1.0, Vector2(4.0, 4.0));
success = saveRGBA("output.rgba", msdf);
}
destroyFont(font);
}
deinitializeFreetype(ft);
}
return success ? 0 : 1;
#else
return 0;
#endif
}

8
all-in-one/vcpkg.json Normal file
View File

@ -0,0 +1,8 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/master/docs/vcpkg.schema.json",
"name": "msdfgen-all-in-one",
"version": "1.10.0",
"dependencies": [
"freetype"
]
}