Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FreeType is a toggleable option which is disabled by default #254

Merged
merged 4 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ logs/
*.tar.gz
*.rar
*.gpg
!vendor/freetype-2.12.1.tar.gz
!vendor/*

# Gradle
.gradletasknamecache
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ tasks.register('generateAst', GenerateAst) {
headerFiles = [
file('include/imgui/imgui.h'),
file('include/imgui/imgui_internal.h'),
file('include/imgui/misc/freetype/imgui_freetype.h'),
file('include/ImGuiFileDialog/ImGuiFileDialog.h'),
file('include/imgui-knobs/imgui-knobs.h'),
file('include/imguizmo/ImGuizmo.h'),
Expand Down
2 changes: 1 addition & 1 deletion buildSrc/scripts/vendor_freetype.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ echo "Vendor type set to '$VTYPE'"

# Define library directory and version
LIBDIR=build/vendor/freetype
VERSION=2.12.1
VERSION=2.13.3

# Clean and create library directory, then extract FreeType source
echo "Cleaning and creating library directory, then extracting FreeType source..."
Expand Down
20 changes: 17 additions & 3 deletions buildSrc/src/main/groovy/tool/generator/GenerateLibs.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,15 @@ class GenerateLibs extends DefaultTask {
spec.from(project.rootProject.file('include/imgui/misc/freetype')) { CopySpec it -> it.include('*.h', '*.cpp') }
spec.into("$jniDir/misc/freetype")
}
enableDefine('IMGUI_ENABLE_FREETYPE')

// Since we give a possibility to build library without enabled freetype - define should be set like that.
replaceSourceFileContent("imconfig.h", "//#define IMGUI_ENABLE_FREETYPE", "#define IMGUI_ENABLE_FREETYPE")

// Binding specific behavior to handle FreeType.
// By defining IMGUI_ENABLE_FREETYPE, Dear ImGui will default to using the FreeType font renderer.
// However, we modify the source code to ensure that, even with this, the STB_TrueType renderer is used instead.
// To use the FreeType font renderer, it must be explicitly forced on the atlas manually.
replaceSourceFileContent("imgui_draw.cpp", "ImGuiFreeType::GetBuilderForFreeType()", "ImFontAtlasGetBuilderForStbTruetype()")
}

// Copy dirent for ImGuiFileDialog
Expand Down Expand Up @@ -181,7 +189,13 @@ class GenerateLibs extends DefaultTask {
target.libraries += ' -lfreetype'
}

void enableDefine(String define) {
new File("$jniDir/imconfig.h").text += "#define $define"
void replaceSourceFileContent(String fileName, String replaceWhat, String replaceWith) {
def sourceFile = new File("$jniDir/$fileName")
def sourceTxt = sourceFile.text
def sourceTxtModified = sourceTxt.replace(replaceWhat, replaceWith)
if (sourceTxt == sourceTxtModified) {
throw new IllegalStateException("Unable to replace [$fileName] with content [$replaceWith]!")
}
sourceFile.text = sourceTxtModified
}
}
17 changes: 16 additions & 1 deletion buildSrc/src/main/kotlin/tool/generator/ast/task/GenerateAst.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.lordcodes.turtle.shellRun
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
Expand All @@ -23,6 +24,8 @@ open class GenerateAst : DefaultTask() {

@InputFiles
lateinit var headerFiles: Collection<File>
@Input
var defines: Set<String> = emptySet()

private val dstDir: File = File("${project.rootDir}/buildSrc/src/main/resources/${AstParser.RESOURCE_PATH}")
private val objectMapper: ObjectMapper = ObjectMapper()
Expand Down Expand Up @@ -403,9 +406,21 @@ open class GenerateAst : DefaultTask() {
}

private fun callClangAstBump(scriptPath: String, srcHeader: File, dstJson: File) {
fun buildCommand(): List<String> {
val command = mutableListOf(
scriptPath,
srcHeader.absolutePath,
dstJson.absolutePath,
)
if (defines.isNotEmpty()) {
command += defines.map { "-D$it" }
}
return command
}

dstJson.delete()
val pb = ProcessBuilder()
pb.command(scriptPath, srcHeader.absolutePath, dstJson.absolutePath)
pb.command(buildCommand())
pb.start().waitFor()
}

Expand Down
20 changes: 19 additions & 1 deletion buildSrc/src/main/resources/generator/api/ast/_gen_ast.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,22 @@
# Java ProcessBuilder doesn't see command properly.
# Also, running like that helps to ignore local clang++ warnings which can happen.

clang++ -Xclang -ast-dump=json -fsyntax-only -fparse-all-comments -fmerge-all-constants "$1" >> "$2"
# Assign the first argument to 'input_file' (the C++ file to analyze).
input_file="$1"

# Assign the second argument to 'output_file' (where to save the AST JSON).
output_file="$2"

# 'shift 2' shifts the positional parameters to the left by two positions.
# This means "$@" will now contain any additional arguments (like macro definitions).
shift 2

# Run clang++ with the specified options.
# -Xclang -ast-dump=json: Dumps the AST in JSON format.
# -fsyntax-only: Only checks the syntax, does not compile.
# -fparse-all-comments: Includes comments in the AST.
# -fmerge-all-constants: Merges identical constants.
# "$@" passes any additional arguments (like -D for macro definitions).
# "$input_file" is the C++ source file to process.
# The output is redirected and appended to the specified output file.
clang++ -Xclang -ast-dump=json -fsyntax-only -fparse-all-comments -fmerge-all-constants "$@" "$input_file" >> "$output_file"
186 changes: 186 additions & 0 deletions buildSrc/src/main/resources/generator/api/ast/ast-imgui_freetype.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
{
"info" : {
"source" : "include/imgui/misc/freetype/imgui_freetype.h",
"hash" : "5976473c3ad2fbe2f0386eaa9019d4e0",
"url" : "https://github.com/ocornut/imgui",
"revision" : "1ee252772ae9c0a971d06257bb5c89f628fa696a"
},
"decls" : [ {
"@type" : "AstRecordDecl",
"name" : "ImFontAtlas",
"decls" : [ {
"@type" : "AstFullComment",
"decls" : [ {
"@type" : "AstParagraphComment",
"decls" : [ {
"@type" : "AstTextComment",
"text" : " Forward declarations"
} ]
} ]
} ]
}, {
"@type" : "AstEnumDecl",
"name" : "ImGuiFreeTypeBuilderFlags",
"decls" : [ {
"@type" : "AstFullComment",
"decls" : [ {
"@type" : "AstParagraphComment",
"decls" : [ {
"@type" : "AstTextComment",
"text" : " Hinting greatly impacts visuals (and glyph sizes)."
}, {
"@type" : "AstTextComment",
"text" : " - By default, hinting is enabled and the font's native hinter is preferred over the auto-hinter."
}, {
"@type" : "AstTextComment",
"text" : " - When disabled, FreeType generates blurrier glyphs, more or less matches the stb_truetype.h"
}, {
"@type" : "AstTextComment",
"text" : " - The Default hinting mode usually looks good, but may distort glyphs in an unusual way."
}, {
"@type" : "AstTextComment",
"text" : " - The Light hinting mode generates fuzzier glyphs but better matches Microsoft's rasterizer."
}, {
"@type" : "AstTextComment",
"text" : " You can set those flags globaly in ImFontAtlas::FontBuilderFlags"
}, {
"@type" : "AstTextComment",
"text" : " You can set those flags on a per font basis in ImFontConfig::FontBuilderFlags"
} ]
} ]
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_NoHinting",
"docComment" : "Disable hinting. This generally generates 'blurrier' bitmap glyphs when the glyph are rendered in any of the anti-aliased modes.",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 0,
"value" : "1 << 0",
"evaluatedValue" : 1
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_NoAutoHint",
"docComment" : "Disable auto-hinter.",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 1,
"value" : "1 << 1",
"evaluatedValue" : 2
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_ForceAutoHint",
"docComment" : "Indicates that the auto-hinter is preferred over the font's native hinter.",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 2,
"value" : "1 << 2",
"evaluatedValue" : 4
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_LightHinting",
"docComment" : "A lighter hinting algorithm for gray-level modes. Many generated glyphs are fuzzier but better resemble their original shape. This is achieved by snapping glyphs to the pixel grid only vertically (Y-axis), as is done by Microsoft's ClearType and Adobe's proprietary font renderer. This preserves inter-glyph spacing in horizontal text.",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 3,
"value" : "1 << 3",
"evaluatedValue" : 8
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_MonoHinting",
"docComment" : "Strong hinting algorithm that should only be used for monochrome output.",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 4,
"value" : "1 << 4",
"evaluatedValue" : 16
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_Bold",
"docComment" : "Styling: Should we artificially embolden the font?",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 5,
"value" : "1 << 5",
"evaluatedValue" : 32
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_Oblique",
"docComment" : "Styling: Should we slant the font, emulating italic style?",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 6,
"value" : "1 << 6",
"evaluatedValue" : 64
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_Monochrome",
"docComment" : "Disable anti-aliasing. Combine this with MonoHinting for best results!",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 7,
"value" : "1 << 7",
"evaluatedValue" : 128
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_LoadColor",
"docComment" : "Enable FreeType color-layered glyphs",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 8,
"value" : "1 << 8",
"evaluatedValue" : 256
}, {
"@type" : "AstEnumConstantDecl",
"name" : "ImGuiFreeTypeBuilderFlags_Bitmap",
"docComment" : "Enable FreeType bitmap glyphs",
"qualType" : "ImGuiFreeTypeBuilderFlags",
"order" : 9,
"value" : "1 << 9",
"evaluatedValue" : 512
} ]
}, {
"@type" : "AstNamespaceDecl",
"name" : "ImGuiFreeType",
"decls" : [ {
"@type" : "AstFunctionDecl",
"name" : "SetAllocatorFunctions",
"resultType" : "int",
"decls" : [ {
"@type" : "AstParmVarDecl",
"name" : "alloc_func",
"qualType" : "void *(*)(int, void *)",
"desugaredQualType" : "void *(*)(int, void *)"
}, {
"@type" : "AstParmVarDecl",
"name" : "free_func",
"qualType" : "void (*)(void *, void *)",
"desugaredQualType" : "void (*)(void *, void *)"
}, {
"@type" : "AstParmVarDecl",
"name" : "user_data",
"qualType" : "void *",
"desugaredQualType" : "void *",
"defaultValue" : "="
}, {
"@type" : "AstFullComment",
"decls" : [ {
"@type" : "AstParagraphComment",
"decls" : [ {
"@type" : "AstTextComment",
"text" : " Override allocators. By default ImGuiFreeType will use IM_ALLOC()/IM_FREE()"
}, {
"@type" : "AstTextComment",
"text" : " However, as FreeType does lots of allocations we provide a way for the user to redirect it to a separate memory heap if desired."
} ]
} ]
} ]
}, {
"@type" : "AstFunctionDecl",
"name" : "BuildFontAtlas",
"resultType" : "bool",
"decls" : [ {
"@type" : "AstParmVarDecl",
"name" : "atlas",
"qualType" : "ImFontAtlas *",
"desugaredQualType" : "ImFontAtlas *"
}, {
"@type" : "AstParmVarDecl",
"name" : "flags",
"qualType" : "unsigned int",
"desugaredQualType" : "unsigned int",
"defaultValue" : "0"
} ]
} ]
} ]
}
6 changes: 5 additions & 1 deletion example/src/main/java/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ protected void initImGui(final Configuration config) {
* For more information read: https://github.com/ocornut/imgui/blob/33cdbe97b8fd233c6c12ca216e76398c2e89b0d8/docs/FONTS.md
*/
private void initFonts(final ImGuiIO io) {
io.getFonts().addFontDefault(); // Add default font for latin glyphs
// This enables FreeType font renderer, which is disabled by default.
io.getFonts().setFreeTypeRenderer(true);

// Add default font for latin glyphs
io.getFonts().addFontDefault();

// You can use the ImFontGlyphRangesBuilder helper to create glyph ranges based on text input.
// For example: for a game where your script is known, if you can feed your entire script to it (using addText) and only build the characters the game needs.
Expand Down
26 changes: 26 additions & 0 deletions imgui-binding/src/generated/java/imgui/ImFontAtlas.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,32 @@ public void clear() {
// Building in RGBA32 format is provided for convenience and compatibility, but note that unless you manually manipulate or copy color data into
// the texture (e.g. when using the AddCustomRect*** api), then the RGB pixels emitted will always be white (~75% of memory/bandwidth waste.

/*JNI
#ifdef IMGUI_ENABLE_FREETYPE
#include "misc/freetype/imgui_freetype.h"
#endif
*/

/**
* <b>BINDING NOTICE:</b> This method is specific to the imgui-java binding.
* <p>
* Since FreeType is included in the final build, it's possible to use both font renderers (STB_TrueType and FreeType) simultaneously without needing to rebuild the library.
* By default, we use small hacks to set STB_TrueType as the default font renderer. However, this method allows you to enforce the use of the FreeType renderer.
* <p>
* This method MUST be called before invoking the "#build" or "#getTexData*" methods.
*
* @param enabled true to enable the FreeType font renderer
*/
public native void setFreeTypeRenderer(boolean enabled); /*
#ifdef IMGUI_ENABLE_FREETYPE
if (enabled) {
THIS->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType();
} else {
THIS->FontBuilderIO = NULL;
}
#endif
*/

/**
* Build pixels data. This is called automatically for you by the GetTexData*** functions.
*/
Expand Down
Loading