Merge pull request #2 from antopilo/develop
Merge current scripting progress to master.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -826,4 +826,6 @@ FodyWeavers.xsd
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
*.sln.iml
|
||||
|
||||
!freetype.lib
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "Nuake/dependencies/glfw"]
|
||||
path = Nuake/dependencies/glfw
|
||||
url = https://github.com/glfw/glfw/tree/master
|
||||
BIN
Editor/resources/Fonts/RobotoMono-Regular.ttf
Normal file
BIN
Editor/resources/Fonts/RobotoMono-Regular.ttf
Normal file
Binary file not shown.
@@ -1,26 +1,10 @@
|
||||
import "Scripts/Math" for Vector3
|
||||
|
||||
class Engine {
|
||||
foreign static Log(msg)
|
||||
}
|
||||
|
||||
class Scene {
|
||||
foreign static GetEntityID(name)
|
||||
|
||||
static GetEntity(name) {
|
||||
var entId = Scene.GetEntityID(name)
|
||||
var ent = Entity.new(entId)
|
||||
return ent
|
||||
}
|
||||
|
||||
foreign static EntityHasComponent(id, name)
|
||||
}
|
||||
|
||||
class Entity {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
HasComponent(component) {
|
||||
return Scene.EntityHasComponent(_entityId, component)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
70
Editor/resources/Scripts/Input.wren
Normal file
70
Editor/resources/Scripts/Input.wren
Normal file
@@ -0,0 +1,70 @@
|
||||
import "Scripts/Math" for Vector3
|
||||
import "Scripts/Engine" for Engine
|
||||
class Input {
|
||||
foreign static GetMouseX()
|
||||
foreign static GetMouseY()
|
||||
|
||||
// Gets the mouse position of X & Y and returns a Vector3
|
||||
static GetMousePos() {
|
||||
var result = Vector3.new(this.GetMouseX_(), this.GetMouseY_(), 0)
|
||||
return result
|
||||
}
|
||||
|
||||
// Keys
|
||||
foreign static IsKeyDown_(key)
|
||||
static IsKeyDown(key) {
|
||||
if(key is Num) {
|
||||
return this.IsKeyDown_(key)
|
||||
}
|
||||
Engine.Log("IsKeyDown expects a number. Got: %(key.type)")
|
||||
}
|
||||
|
||||
foreign static IsKeyPressed_(key)
|
||||
static IsKeyPressed(key) {
|
||||
if(key is Num){
|
||||
return this.IsKeyPressed_(key)
|
||||
}
|
||||
|
||||
Engine.Log("IsKeyPressed expects a number. Got: %(key.type)")
|
||||
}
|
||||
|
||||
foreign static IsKeyReleased_(key)
|
||||
static IsKeyReleased(key) {
|
||||
if(key is Num) {
|
||||
return this.IsKeyReleased_(key)
|
||||
}
|
||||
|
||||
Engine.Log("IsKeyReleased expects a number. Got: %(key.type)")
|
||||
}
|
||||
|
||||
// Mouse
|
||||
foreign static IsMouseButtonDown_(button)
|
||||
static IsMouseButtonDown(button) {
|
||||
if(button is Num){
|
||||
return this.IsMouseButtonDown_(button)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreign static IsMouseButtonPressed_(button)
|
||||
static IsMouseButtonPressed(button) {
|
||||
if(button is Num) {
|
||||
Engine.Log("IsmouseButtonPressed: %(button)")
|
||||
return this.IsMouseButtonPressed_(button)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreign static IsMouseButtonReleased_(button)
|
||||
static IsMouseButtonReleased(button) {
|
||||
if(button is Num){
|
||||
return this.IsMouseButtonReleased_(button)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreign static HideMouse()
|
||||
foreign static ShowMouse()
|
||||
foreign static IsMouseHidden()
|
||||
|
||||
}
|
||||
69
Editor/resources/Scripts/Math.wren
Normal file
69
Editor/resources/Scripts/Math.wren
Normal file
@@ -0,0 +1,69 @@
|
||||
class Math {
|
||||
foreign static Sqrt_(x, y, z)
|
||||
}
|
||||
|
||||
class Vector3 {
|
||||
|
||||
x {_x}
|
||||
y {_y}
|
||||
z {_z}
|
||||
x=(value) {
|
||||
_x = value
|
||||
}
|
||||
y=(value) {
|
||||
_y = value
|
||||
}
|
||||
z=(value) {
|
||||
_z = value
|
||||
}
|
||||
|
||||
mul(other) {
|
||||
if(other is Vector3) {
|
||||
return Vector3.new(_x * other.x,
|
||||
_y * other.y,
|
||||
_z * other.z)
|
||||
} else {
|
||||
return Vector3.new(_x * other, _y * other, _z * other)
|
||||
}
|
||||
}
|
||||
|
||||
*(other) {
|
||||
if(other is Vector3) {
|
||||
return Vector3.new(_x * other.x,
|
||||
_y * other.y,
|
||||
_z * other.z)
|
||||
} else if(other is Num) {
|
||||
return Vector3.new(_x * other, _y * other, _z * other)
|
||||
}
|
||||
}
|
||||
|
||||
+(other) {
|
||||
if(other is Vector3) {
|
||||
return Vector3.new(_x + other.x,
|
||||
_y + other.y,
|
||||
_z + other.z)
|
||||
} else if(other is Num) {
|
||||
return Vector3.new(_x + other,
|
||||
_y + other,
|
||||
_z + other)
|
||||
}
|
||||
}
|
||||
|
||||
construct new(x, y, z) {
|
||||
_x = x
|
||||
_y = y
|
||||
_z = z
|
||||
}
|
||||
|
||||
Sqrt() {
|
||||
return Math.Sqrt_(_x, _y, _z)
|
||||
}
|
||||
|
||||
Normalize() {
|
||||
var length = this.Sqrt()
|
||||
var x = _x / length
|
||||
var y = _y / length
|
||||
var z = _z / length
|
||||
return Vector3.new(x, y, z)
|
||||
}
|
||||
}
|
||||
155
Editor/resources/Scripts/Scene.wren
Normal file
155
Editor/resources/Scripts/Scene.wren
Normal file
@@ -0,0 +1,155 @@
|
||||
import "Scripts/Engine" for Engine
|
||||
import "Scripts/Math" for Vector3
|
||||
|
||||
class Scene {
|
||||
foreign static GetEntityID(name)
|
||||
|
||||
|
||||
static GetEntity(name) {
|
||||
var entId = Scene.GetEntityID(name)
|
||||
var ent = Entity.new(entId)
|
||||
return ent
|
||||
}
|
||||
|
||||
foreign static EntityHasComponent(id, name)
|
||||
static EntityGetComponent(id, component) {
|
||||
if(this.EntityHasComponent(id, component) == false) {
|
||||
Engine.Log("Tried getting a non-existent component of type: %(component) on entity with id: %(id)")
|
||||
return
|
||||
}
|
||||
|
||||
if (component == "Light") {
|
||||
return Light.new(id)
|
||||
} else if (component == "CharacterController") {
|
||||
return CharacterController.new(id)
|
||||
} else if (component == "Camera") {
|
||||
return Camera.new(id)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Components
|
||||
//
|
||||
// Transform
|
||||
//foreign static SetTranslation_(e, x, y, z)
|
||||
//foreign static SetRotation_(e, x, y, z)
|
||||
//foreign static SetScale_(e, x, y, z)
|
||||
|
||||
// Light
|
||||
foreign static GetLightIntensity_(e) // returns a float
|
||||
foreign static SetLightIntensity_(e, intensity)
|
||||
//foreign static SetLightIsVolumetric_(e, bool)
|
||||
//foreign static SetLightSyncDirectionWithSky_(e, bool)
|
||||
//foreign static SetLightColor_(e, r, g, b)
|
||||
//foreign static GetLightColor_(e)
|
||||
|
||||
// Camera
|
||||
foreign static SetCameraDirection_(e, x, y, z)
|
||||
foreign static GetCameraDirection_(e) // returns a list x,y,z
|
||||
foreign static GetCameraRight_(e) // returns a list x,y,z
|
||||
//foreign static SetcameraFov(e, fov)
|
||||
//foreign static GetCameraFov(e) // returns a float
|
||||
|
||||
// Character controller
|
||||
foreign static MoveAndSlide_(e, x, y, z)
|
||||
//foreign static IsOnGround_(e)
|
||||
|
||||
|
||||
}
|
||||
|
||||
class Entity {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
HasComponent(component) {
|
||||
return Scene.EntityHasComponent(_entityId, component)
|
||||
}
|
||||
|
||||
GetComponent(component) {
|
||||
return Scene.EntityGetComponent(_entityId, component)
|
||||
}
|
||||
|
||||
// Foreign engine functions
|
||||
/*
|
||||
// Transform
|
||||
foreign static SetTranslation_(e, x, y, z)
|
||||
foreign static SetRotation_(e, x, y, z)
|
||||
foreign static SetScale_(e, x, y, z)
|
||||
|
||||
// Character controller
|
||||
foreign static SetVelocity(e, x, y, z)
|
||||
foreign static SetStepHeight(e, x, y, z)
|
||||
foreign static IsOnGround(e)
|
||||
*/
|
||||
// Light
|
||||
//
|
||||
/*
|
||||
foreign static SetLightIsVolumetric_(e, bool)
|
||||
foreign static SetLightSyncDirectionWithSky_(e, bool)
|
||||
foreign static SetLightColor_(e, r, g, b)
|
||||
|
||||
// Camera
|
||||
foreign static SetCameraFov_(e, fov)
|
||||
foreign static SetCameraType(e, type)
|
||||
foreign static SetCameraDirection_(e, x, y, z)
|
||||
*/
|
||||
}
|
||||
|
||||
class Light {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
|
||||
SetIntensity(intensity) {
|
||||
Scene.SetLightIntensity_(_entityId, intensity)
|
||||
}
|
||||
|
||||
GetIntensity() {
|
||||
return Scene.GetLightIntensity_(_entityId)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SetType(type) {
|
||||
this.SetType_(_entityId, type)
|
||||
}
|
||||
|
||||
SetColor(color) {
|
||||
this.SetColor_(_entityId, color.r, color.g, color.b, color.a)
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
class CharacterController {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
MoveAndSlide(vel) {
|
||||
Scene.MoveAndSlide_(_entityId, vel.x, vel.y, vel.z)
|
||||
}
|
||||
}
|
||||
|
||||
class Camera {
|
||||
construct new(id) {
|
||||
_entityId = id
|
||||
}
|
||||
|
||||
SetDirection(dir) {
|
||||
Scene.SetCameraDirection_(_entityId, dir.x, dir.y, dir.z)
|
||||
}
|
||||
|
||||
GetDirection() {
|
||||
var dir = Scene.GetCameraDirection_(_entityId)
|
||||
return Vector3.new(dir[0], dir[1], dir[2])
|
||||
}
|
||||
|
||||
GetRight() {
|
||||
var dir = Scene.GetCameraRight_(_entityId)
|
||||
return Vector3.new(dir[0], dir[1], dir[2])
|
||||
}
|
||||
|
||||
}
|
||||
15
Editor/resources/Scripts/ScriptableEntity.wren
Normal file
15
Editor/resources/Scripts/ScriptableEntity.wren
Normal file
@@ -0,0 +1,15 @@
|
||||
import "Scripts/Scene" for Scene
|
||||
|
||||
class ScriptableEntity {
|
||||
SetEntityId(id) {
|
||||
_EntityID = id
|
||||
}
|
||||
|
||||
GetComponent(component) {
|
||||
return Scene.EntityGetComponent(_EntityID, component)
|
||||
}
|
||||
|
||||
HasComponent(component) {
|
||||
return Scene.EntityHasComponent(_EntityID, component)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
import "Scripts/Engine" for Engine, Scene, Entity
|
||||
import "Scripts/Engine" for Engine
|
||||
import "Scripts/Input" for Input
|
||||
import "Scripts/Scene" for Scene, Entity
|
||||
|
||||
class Test {
|
||||
init() {
|
||||
System.print("hello init")
|
||||
@@ -13,10 +16,12 @@ class Test {
|
||||
}
|
||||
|
||||
static hello() {
|
||||
var entity = Scene.GetEntity("Trenchbroom map")
|
||||
var hasTransform = entity.HasComponent("Transform")
|
||||
var hasLight = entity.HasComponent("Light")
|
||||
var entity = Scene.GetEntity("Light")
|
||||
var light = entity.GetComponent("Light")
|
||||
light.SetIntensity(1.0)
|
||||
|
||||
Engine.Log("trasnform: %(hasTransform) light:%(hasLight)")
|
||||
if(Input.IsMouseButtonPressed(2) == true) {
|
||||
Engine.Log("RIGHT CLICK!!!!!!")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "src/Resource/Project.h"
|
||||
#include <src/Scene/Entities/Components/LuaScriptComponent.h>
|
||||
#include <src/Core/Logger.h>
|
||||
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
|
||||
Ref<UI::UserInterface> userInterface;
|
||||
ImFont* normalFont;
|
||||
ImFont* EditorInterface::bigIconFont;
|
||||
@@ -80,7 +81,7 @@ void EditorInterface::DrawViewport()
|
||||
glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y);
|
||||
|
||||
if(Engine::GetCurrentWindow()->GetFrameBuffer()->GetSize() != viewportPanelSize)
|
||||
Engine::GetCurrentWindow()->GetFrameBuffer()->UpdateSize(viewportPanelSize);
|
||||
Engine::GetCurrentWindow()->GetFrameBuffer()->QueueResize(viewportPanelSize);
|
||||
|
||||
Ref<Texture> texture = Engine::GetCurrentWindow()->GetFrameBuffer()->GetTexture();
|
||||
ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0));
|
||||
@@ -321,16 +322,22 @@ void EditorInterface::DrawEntityPropreties()
|
||||
}
|
||||
if (ImGui::BeginPopup("add_component_popup"))
|
||||
{
|
||||
if (ImGui::MenuItem("Lua script") && !m_SelectedEntity.HasComponent<LuaScriptComponent>())
|
||||
m_SelectedEntity.AddComponent<LuaScriptComponent>();
|
||||
if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent<LightComponent>())
|
||||
m_SelectedEntity.AddComponent<LightComponent>();
|
||||
if (ImGui::MenuItem("Mesh Component") && !m_SelectedEntity.HasComponent<MeshComponent>())
|
||||
m_SelectedEntity.AddComponent<MeshComponent>();
|
||||
if (ImGui::MenuItem("Wren Script") && !m_SelectedEntity.HasComponent<WrenScriptComponent>())
|
||||
m_SelectedEntity.AddComponent<WrenScriptComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Camera Component") && !m_SelectedEntity.HasComponent<CameraComponent>())
|
||||
m_SelectedEntity.AddComponent<CameraComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Light Component") && !m_SelectedEntity.HasComponent<LightComponent>())
|
||||
m_SelectedEntity.AddComponent<LightComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Mesh Component") && !m_SelectedEntity.HasComponent<MeshComponent>())
|
||||
m_SelectedEntity.AddComponent<MeshComponent>();
|
||||
if (ImGui::MenuItem("Quake map Component") && !m_SelectedEntity.HasComponent<QuakeMapComponent>())
|
||||
m_SelectedEntity.AddComponent<QuakeMapComponent>();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Character controller") && !m_SelectedEntity.HasComponent<CharacterControllerComponent>())
|
||||
m_SelectedEntity.AddComponent<CharacterControllerComponent>();
|
||||
if (ImGui::MenuItem("Rigidbody Component") && !m_SelectedEntity.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
m_SelectedEntity.AddComponent<RigidBodyComponent>();
|
||||
@@ -377,32 +384,43 @@ void EditorInterface::DrawEntityPropreties()
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<LuaScriptComponent>()) {
|
||||
if (m_SelectedEntity.HasComponent<WrenScriptComponent>()) {
|
||||
std::string icon = ICON_FA_FILE;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Lua script").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Wren Script").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
auto& component = m_SelectedEntity.GetComponent<LuaScriptComponent>();
|
||||
auto& component = m_SelectedEntity.GetComponent<WrenScriptComponent>();
|
||||
|
||||
// Path
|
||||
std::string path = component.Script;
|
||||
|
||||
|
||||
char pathBuffer[256];
|
||||
|
||||
memset(pathBuffer, 0, sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer));
|
||||
|
||||
if (ImGui::InputText("##ScriptPath", pathBuffer, sizeof(pathBuffer)))
|
||||
{
|
||||
path = std::string(pathBuffer);
|
||||
}
|
||||
path = FileSystem::AbsoluteToRelative(std::string(pathBuffer));
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Browse"))
|
||||
{
|
||||
path = FileDialog::OpenFile(".map");
|
||||
}
|
||||
path = FileSystem::AbsoluteToRelative(FileDialog::OpenFile(".wren"));
|
||||
|
||||
component.Script = path;
|
||||
|
||||
// Class
|
||||
std::string module = component.Class;
|
||||
|
||||
char classBuffer[256];
|
||||
|
||||
memset(classBuffer, 0, sizeof(classBuffer));
|
||||
std::strncpy(classBuffer, module.c_str(), sizeof(classBuffer));
|
||||
|
||||
if (ImGui::InputText("##ScriptModule", classBuffer, sizeof(classBuffer)))
|
||||
module = std::string(classBuffer);
|
||||
|
||||
component.Class = module;
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<CameraComponent>()) {
|
||||
@@ -416,6 +434,18 @@ void EditorInterface::DrawEntityPropreties()
|
||||
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<CharacterControllerComponent>())
|
||||
{
|
||||
if (ImGui::CollapsingHeader("Character controller", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
auto& c = m_SelectedEntity.GetComponent<CharacterControllerComponent>();
|
||||
ImGui::InputFloat("Height", &c.Height);
|
||||
ImGui::InputFloat("Radius", &c.Radius);
|
||||
ImGui::InputFloat("Mass", &c.Mass);
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SelectedEntity.HasComponent<MeshComponent>()) {
|
||||
|
||||
std::string icon = ICON_FA_TREE;
|
||||
@@ -907,17 +937,26 @@ void OpenProject()
|
||||
Engine::LoadProject(project);
|
||||
|
||||
// Create new interface named test.
|
||||
userInterface = UI::UserInterface::New("test");
|
||||
//userInterface = UI::UserInterface::New("test");
|
||||
|
||||
|
||||
// Set current interface running.
|
||||
Engine::GetCurrentScene()->AddInterface(userInterface);
|
||||
|
||||
//Engine::GetCurrentScene()->AddInterface(userInterface);
|
||||
}
|
||||
|
||||
void OpenScene()
|
||||
{
|
||||
// Parse the project and load it.
|
||||
std::string projectPath = FileDialog::OpenFile(".scene");
|
||||
|
||||
Ref<Scene> scene = Scene::New();
|
||||
if (!scene->Deserialize(FileSystem::ReadFile(projectPath, true))) {
|
||||
Logger::Log("Error failed loading scene: " + projectPath);
|
||||
return;
|
||||
}
|
||||
|
||||
scene->Path = FileSystem::AbsoluteToRelative(projectPath);
|
||||
Engine::LoadScene(scene);
|
||||
}
|
||||
|
||||
void EditorInterface::DrawInit()
|
||||
@@ -981,6 +1020,10 @@ void EditorInterface::Draw()
|
||||
m_IsEntitySelected = false;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Set current scene as default")) {
|
||||
Engine::GetProject()->DefaultScene = Engine::GetCurrentScene();
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Open scene...", "CTRL+O"))
|
||||
{
|
||||
OpenScene();
|
||||
|
||||
@@ -24,8 +24,6 @@ void Engine::Init()
|
||||
PhysicsManager::Get()->Init();
|
||||
Logger::Log("Physics initialized");
|
||||
|
||||
ScriptingEngine::Init();
|
||||
Logger::Log("Scripting engine initialized");
|
||||
|
||||
CurrentWindow = Window::Get();
|
||||
Logger::Log("Window initialized");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,525 +0,0 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.3 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _glfw3_native_h_
|
||||
#define _glfw3_native_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Doxygen documentation
|
||||
*************************************************************************/
|
||||
|
||||
/*! @file glfw3native.h
|
||||
* @brief The header of the native access functions.
|
||||
*
|
||||
* This is the header file of the native access functions. See @ref native for
|
||||
* more information.
|
||||
*/
|
||||
/*! @defgroup native Native access
|
||||
* @brief Functions related to accessing native handles.
|
||||
*
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||
* window system API macro and zero or more context creation API macros.
|
||||
*
|
||||
* The chosen backends must match those the library was compiled for. Failure
|
||||
* to do this will cause a link-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||
*
|
||||
* The available context API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||
*
|
||||
* These macros select which of the native access functions that are declared
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* defined.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Functions
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
|
||||
/*! @brief Sets the current primary selection to the specified string.
|
||||
*
|
||||
* @param[in] string A UTF-8 encoded string.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified string is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwGetX11SelectionString
|
||||
* @sa glfwSetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||
|
||||
/*! @brief Returns the contents of the current primary selection as a string.
|
||||
*
|
||||
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||
*
|
||||
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||
* if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the next call to @ref
|
||||
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||
* library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwSetX11SelectionString
|
||||
* @sa glfwGetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||
*
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||
*
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
|
||||
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||
*
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||
*
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose color buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||
* buffer, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the color buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||
|
||||
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose depth buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||
* buffer element, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||
|
||||
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||
*
|
||||
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _glfw3_native_h_ */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,525 +0,0 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.3 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _glfw3_native_h_
|
||||
#define _glfw3_native_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Doxygen documentation
|
||||
*************************************************************************/
|
||||
|
||||
/*! @file glfw3native.h
|
||||
* @brief The header of the native access functions.
|
||||
*
|
||||
* This is the header file of the native access functions. See @ref native for
|
||||
* more information.
|
||||
*/
|
||||
/*! @defgroup native Native access
|
||||
* @brief Functions related to accessing native handles.
|
||||
*
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||
* window system API macro and zero or more context creation API macros.
|
||||
*
|
||||
* The chosen backends must match those the library was compiled for. Failure
|
||||
* to do this will cause a link-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||
*
|
||||
* The available context API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||
*
|
||||
* These macros select which of the native access functions that are declared
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* defined.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Functions
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
|
||||
/*! @brief Sets the current primary selection to the specified string.
|
||||
*
|
||||
* @param[in] string A UTF-8 encoded string.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified string is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwGetX11SelectionString
|
||||
* @sa glfwSetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||
|
||||
/*! @brief Returns the contents of the current primary selection as a string.
|
||||
*
|
||||
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||
*
|
||||
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||
* if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the next call to @ref
|
||||
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||
* library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwSetX11SelectionString
|
||||
* @sa glfwGetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||
*
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||
*
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
|
||||
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||
*
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||
*
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose color buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||
* buffer, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the color buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||
|
||||
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose depth buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||
* buffer element, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||
|
||||
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||
*
|
||||
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _glfw3_native_h_ */
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -1,525 +0,0 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.3 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _glfw3_native_h_
|
||||
#define _glfw3_native_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Doxygen documentation
|
||||
*************************************************************************/
|
||||
|
||||
/*! @file glfw3native.h
|
||||
* @brief The header of the native access functions.
|
||||
*
|
||||
* This is the header file of the native access functions. See @ref native for
|
||||
* more information.
|
||||
*/
|
||||
/*! @defgroup native Native access
|
||||
* @brief Functions related to accessing native handles.
|
||||
*
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||
* window system API macro and zero or more context creation API macros.
|
||||
*
|
||||
* The chosen backends must match those the library was compiled for. Failure
|
||||
* to do this will cause a link-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||
*
|
||||
* The available context API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||
*
|
||||
* These macros select which of the native access functions that are declared
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* defined.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Functions
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
|
||||
/*! @brief Sets the current primary selection to the specified string.
|
||||
*
|
||||
* @param[in] string A UTF-8 encoded string.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified string is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwGetX11SelectionString
|
||||
* @sa glfwSetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||
|
||||
/*! @brief Returns the contents of the current primary selection as a string.
|
||||
*
|
||||
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||
*
|
||||
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||
* if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the next call to @ref
|
||||
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||
* library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwSetX11SelectionString
|
||||
* @sa glfwGetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||
*
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||
*
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
|
||||
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||
*
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||
*
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose color buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||
* buffer, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the color buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||
|
||||
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose depth buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||
* buffer element, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||
|
||||
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||
*
|
||||
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _glfw3_native_h_ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,525 +0,0 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.3 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would
|
||||
* be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _glfw3_native_h_
|
||||
#define _glfw3_native_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Doxygen documentation
|
||||
*************************************************************************/
|
||||
|
||||
/*! @file glfw3native.h
|
||||
* @brief The header of the native access functions.
|
||||
*
|
||||
* This is the header file of the native access functions. See @ref native for
|
||||
* more information.
|
||||
*/
|
||||
/*! @defgroup native Native access
|
||||
* @brief Functions related to accessing native handles.
|
||||
*
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you may define zero or more
|
||||
* window system API macro and zero or more context creation API macros.
|
||||
*
|
||||
* The chosen backends must match those the library was compiled for. Failure
|
||||
* to do this will cause a link-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
* * `GLFW_EXPOSE_NATIVE_COCOA`
|
||||
* * `GLFW_EXPOSE_NATIVE_X11`
|
||||
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
|
||||
*
|
||||
* The available context API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_NSGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_GLX`
|
||||
* * `GLFW_EXPOSE_NATIVE_EGL`
|
||||
* * `GLFW_EXPOSE_NATIVE_OSMESA`
|
||||
*
|
||||
* These macros select which of the native access functions that are declared
|
||||
* and which platform-specific headers to include. It is then up your (by
|
||||
* definition platform-specific) code to handle which of these should be
|
||||
* defined.
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* System headers and types
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#if defined(GLFW_APIENTRY_DEFINED)
|
||||
#undef APIENTRY
|
||||
#undef GLFW_APIENTRY_DEFINED
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
typedef void* id;
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
#include <wayland-client.h>
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/* WGL is declared by windows.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/* NSGL is declared by Cocoa.h */
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
#include <GL/glx.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#endif
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
#include <GL/osmesa.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* Functions
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
|
||||
/*! @brief Sets the current primary selection to the specified string.
|
||||
*
|
||||
* @param[in] string A UTF-8 encoded string.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The specified string is copied before this function
|
||||
* returns.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwGetX11SelectionString
|
||||
* @sa glfwSetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI void glfwSetX11SelectionString(const char* string);
|
||||
|
||||
/*! @brief Returns the contents of the current primary selection as a string.
|
||||
*
|
||||
* If the selection is empty or if its contents cannot be converted, `NULL`
|
||||
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
|
||||
*
|
||||
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
|
||||
* if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the next call to @ref
|
||||
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
|
||||
* library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref clipboard
|
||||
* @sa glfwSetX11SelectionString
|
||||
* @sa glfwGetClipboardString
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetX11SelectionString(void);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `GLXWindow` of the specified window.
|
||||
*
|
||||
* @return The `GLXWindow` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
|
||||
/*! @brief Returns the `struct wl_display*` used by GLFW.
|
||||
*
|
||||
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
|
||||
|
||||
/*! @brief Returns the `struct wl_output*` of the specified monitor.
|
||||
*
|
||||
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the main `struct wl_surface*` of the specified window.
|
||||
*
|
||||
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
|
||||
/*! @brief Retrieves the color buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose color buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the color buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the color buffer, or `NULL`.
|
||||
* @param[out] format Where to store the OSMesa pixel format of the color
|
||||
* buffer, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the color buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
|
||||
|
||||
/*! @brief Retrieves the depth buffer associated with the specified window.
|
||||
*
|
||||
* @param[in] window The window whose depth buffer to retrieve.
|
||||
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
|
||||
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
|
||||
* @param[out] bytesPerValue Where to store the number of bytes per depth
|
||||
* buffer element, or `NULL`.
|
||||
* @param[out] buffer Where to store the address of the depth buffer, or
|
||||
* `NULL`.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
|
||||
|
||||
/*! @brief Returns the `OSMesaContext` of the specified window.
|
||||
*
|
||||
* @return The `OSMesaContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _glfw3_native_h_ */
|
||||
|
||||
Binary file not shown.
@@ -38,6 +38,18 @@ void Camera::OnWindowResize(int x, int y)
|
||||
float height = y;
|
||||
}
|
||||
|
||||
void Camera::SetDirection(Vector3 direction)
|
||||
{
|
||||
//cam->cameraDirection.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
//cam->cameraDirection.y = sin(glm::radians(Pitch));
|
||||
//cam->cameraDirection.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
//cam->cameraFront = glm::normalize(cam->cameraDirection);
|
||||
//cam->cameraRight = glm::normalize(glm::cross(cam->up, cam->cameraFront));
|
||||
cameraDirection = glm::normalize(direction);
|
||||
cameraFront = cameraDirection;
|
||||
cameraRight = glm::normalize(glm::cross(up, cameraFront));
|
||||
}
|
||||
|
||||
glm::vec3 Camera::GetTranslation() {
|
||||
return Translation;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,13 @@ class Camera : public ISerializable
|
||||
private:
|
||||
CAMERA_TYPE m_Type;
|
||||
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
|
||||
Vector3 Rotation = { 0.0f, 0.0f, 0.0f };
|
||||
Vector3 Scale = { 1.0f, 1.0f, 1.0f };
|
||||
Matrix4 m_Perspective;
|
||||
|
||||
public:
|
||||
float AspectRatio = 16.0f / 9.0f;
|
||||
// TODO: remove duplicate direction and have a proper api.
|
||||
Vector3 up = Vector3(0.0f, 1.0f, 0.0f);
|
||||
Vector3 cameraFront = Vector3(0.0f, 0.0f, 1.0f);
|
||||
@@ -42,6 +43,8 @@ public:
|
||||
void SetType(CAMERA_TYPE type);
|
||||
void OnWindowResize(int x, int y);
|
||||
|
||||
void SetDirection(Vector3 direction);
|
||||
|
||||
Vector3 GetTranslation();
|
||||
Vector3 GetDirection();
|
||||
Matrix4 GetPerspective();
|
||||
|
||||
@@ -55,6 +55,9 @@ void FrameBuffer::SetTexture(Ref<Texture> texture, GLenum attachment)
|
||||
|
||||
void FrameBuffer::Bind()
|
||||
{
|
||||
if (ResizeQueued)
|
||||
UpdateSize(m_Size);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_FramebufferID);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glViewport(0, 0, m_Size.x, m_Size.y);
|
||||
@@ -65,6 +68,12 @@ void FrameBuffer::Unbind()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::QueueResize(Vector2 size)
|
||||
{
|
||||
ResizeQueued = true;
|
||||
m_Size = size;
|
||||
}
|
||||
|
||||
void FrameBuffer::UpdateSize(Vector2 size)
|
||||
{
|
||||
m_Size = size;
|
||||
|
||||
@@ -11,7 +11,8 @@ private:
|
||||
unsigned int m_RenderBuffer;
|
||||
|
||||
Vector2 m_Size;
|
||||
|
||||
bool ResizeQueued = false;
|
||||
|
||||
std::map<int, Ref<Texture>> m_Textures;
|
||||
Ref<Texture> m_Texture;
|
||||
|
||||
@@ -27,6 +28,7 @@ public:
|
||||
|
||||
void Bind();
|
||||
void Unbind();
|
||||
void QueueResize(Vector2 size);
|
||||
Vector2 GetSize() const { return m_Size; }
|
||||
void UpdateSize(Vector2 size);
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ int Shader::FindUniformLocation(std::string uniform) {
|
||||
if (addr == -1)
|
||||
std::cout << "Warning: uniform '" << uniform << "' doesn't exists!" << std::endl;
|
||||
else {
|
||||
std::cout << "Info: uniform '" << uniform << "' registered." << std::endl;
|
||||
//std::cout << "Info: uniform '" << uniform << "' registered." << std::endl;
|
||||
UniformCache[uniform] = addr;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,8 @@ void Project::Save()
|
||||
|
||||
void Project::SaveAs(const std::string FullPath)
|
||||
{
|
||||
// Serialize the scene.
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Name);
|
||||
SERIALIZE_VAL(Description);
|
||||
|
||||
json j = Serialize();
|
||||
// Dump.
|
||||
std::string serialized_string = j.dump();
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ void EditorCamera::Update(Timestep ts)
|
||||
float x = Input::GetMouseX();
|
||||
float y = Input::GetMouseY();
|
||||
|
||||
if (!controlled && Input::IsMouseButtonPressed(1))
|
||||
if (!controlled && Input::IsMouseButtonDown(1))
|
||||
{
|
||||
mouseLastX = x;
|
||||
mouseLastY = y;
|
||||
}
|
||||
|
||||
controlled = Input::IsMouseButtonPressed(1);
|
||||
controlled = Input::IsMouseButtonDown(1);
|
||||
|
||||
if (!controlled)
|
||||
Input::ShowMouse();
|
||||
@@ -36,30 +36,30 @@ void EditorCamera::Update(Timestep ts)
|
||||
}
|
||||
|
||||
if (m_Type == CAMERA_TYPE::ORTHO) {
|
||||
if (Input::IsKeyPressed(GLFW_KEY_RIGHT))
|
||||
if (Input::IsKeyDown(GLFW_KEY_RIGHT))
|
||||
Translation.x += Speed * ts;
|
||||
if (Input::IsKeyPressed(GLFW_KEY_LEFT))
|
||||
if (Input::IsKeyDown(GLFW_KEY_LEFT))
|
||||
Translation.x -= Speed * ts;
|
||||
if (Input::IsKeyPressed(GLFW_KEY_UP))
|
||||
if (Input::IsKeyDown(GLFW_KEY_UP))
|
||||
Translation.y += Speed * ts;
|
||||
if (Input::IsKeyPressed(GLFW_KEY_DOWN))
|
||||
if (Input::IsKeyDown(GLFW_KEY_DOWN))
|
||||
Translation.y -= Speed * ts;
|
||||
}
|
||||
else {
|
||||
glm::vec3 movement = glm::vec3(0, 0, 0);
|
||||
|
||||
if (Input::IsKeyPressed(GLFW_KEY_D))
|
||||
if (Input::IsKeyDown(GLFW_KEY_D))
|
||||
movement -= cameraRight * (Speed * ts);
|
||||
if (Input::IsKeyPressed(GLFW_KEY_A))
|
||||
if (Input::IsKeyDown(GLFW_KEY_A))
|
||||
movement += cameraRight * (Speed * ts);
|
||||
|
||||
if (Input::IsKeyPressed(GLFW_KEY_W))
|
||||
if (Input::IsKeyDown(GLFW_KEY_W))
|
||||
movement += cameraDirection * (Speed * ts);
|
||||
if (Input::IsKeyPressed(GLFW_KEY_S))
|
||||
if (Input::IsKeyDown(GLFW_KEY_S))
|
||||
movement -= cameraDirection * (Speed * ts);
|
||||
if (Input::IsKeyPressed(GLFW_KEY_LEFT_SHIFT))
|
||||
if (Input::IsKeyDown(GLFW_KEY_LEFT_SHIFT))
|
||||
movement -= up * (Speed * ts);
|
||||
if (Input::IsKeyPressed(GLFW_KEY_SPACE))
|
||||
if (Input::IsKeyDown(GLFW_KEY_SPACE))
|
||||
movement += up * (Speed * ts);
|
||||
|
||||
Translation += Vector3(movement);
|
||||
|
||||
8
Nuake/src/Scene/Entities/Components/InterfaceComponent.h
Normal file
8
Nuake/src/Scene/Entities/Components/InterfaceComponent.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "../Core/Core.h"
|
||||
#include <src/UI/UserInterface.h>
|
||||
|
||||
class InterfaceComponent
|
||||
{
|
||||
Ref<UI::UserInterface> Interface;
|
||||
};
|
||||
31
Nuake/src/Scene/Entities/Components/WrenScriptComponent.h
Normal file
31
Nuake/src/Scene/Entities/Components/WrenScriptComponent.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "../Scripting/WrenScript.h"
|
||||
|
||||
class WrenScriptComponent
|
||||
{
|
||||
public:
|
||||
std::string Script;
|
||||
std::string Class;
|
||||
|
||||
Ref<WrenScript> WrenScript;
|
||||
|
||||
json Serialize()
|
||||
{
|
||||
BEGIN_SERIALIZE();
|
||||
SERIALIZE_VAL(Script);
|
||||
SERIALIZE_VAL(Class);
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
bool Deserialize(std::string str)
|
||||
{
|
||||
BEGIN_DESERIALIZE();
|
||||
if (j.contains("Script"))
|
||||
Script = j["Script"];
|
||||
if (j.contains("Class"))
|
||||
Class = j["Class"];
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Components/QuakeMap.h"
|
||||
#include "Components/LightComponent.h"
|
||||
#include "Components/QuakeMap.h"
|
||||
#include <src/Scene/Entities/Components/WrenScriptComponent.h>
|
||||
void Entity::AddChild(Entity ent)
|
||||
{
|
||||
if ((int)m_EntityHandle != ent.GetHandle())
|
||||
@@ -31,6 +32,8 @@ json Entity::Serialize()
|
||||
SERIALIZE_OBJECT_REF_LBL("QuakeMapComponent", GetComponent<QuakeMapComponent>());
|
||||
if (HasComponent<LightComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("LightComponent", GetComponent<LightComponent>());
|
||||
if (HasComponent<WrenScriptComponent>())
|
||||
SERIALIZE_OBJECT_REF_LBL("WrenScriptComponent", GetComponent<WrenScriptComponent>());
|
||||
END_SERIALIZE();
|
||||
}
|
||||
|
||||
@@ -43,6 +46,7 @@ bool Entity::Deserialize(const std::string& str)
|
||||
DESERIALIZE_COMPONENT(CameraComponent);
|
||||
DESERIALIZE_COMPONENT(QuakeMapComponent);
|
||||
DESERIALIZE_COMPONENT(LightComponent);
|
||||
DESERIALIZE_COMPONENT(WrenScriptComponent);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "../Scene/Entities/Components/LuaScriptComponent.h"
|
||||
#include <fstream>
|
||||
#include <streambuf>
|
||||
|
||||
#include "../Scene/Entities/Components/WrenScriptComponent.h"
|
||||
Ref<Scene> Scene::New()
|
||||
{
|
||||
return CreateRef<Scene>();
|
||||
@@ -44,6 +44,8 @@ bool Scene::SetName(std::string& newName)
|
||||
|
||||
void Scene::OnInit()
|
||||
{
|
||||
ScriptingEngine::Init();
|
||||
|
||||
// Create physic world.
|
||||
auto view = m_Registry.view<TransformComponent, RigidBodyComponent>();
|
||||
for (auto e : view)
|
||||
@@ -98,10 +100,19 @@ void Scene::OnInit()
|
||||
|
||||
// Instanciate scripts.
|
||||
{
|
||||
m_Registry.view<LuaScriptComponent>().each([=](auto entity, auto& nsc)
|
||||
auto entities = m_Registry.view<WrenScriptComponent>();
|
||||
for (auto& e : entities)
|
||||
{
|
||||
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
||||
if (wren.Script != "" && wren.Class != "")
|
||||
wren.WrenScript = CreateRef<WrenScript>(wren.Script, wren.Class, true);
|
||||
|
||||
});
|
||||
if (wren.WrenScript != nullptr)
|
||||
{
|
||||
wren.WrenScript->SetScriptableEntityID((int)e);
|
||||
wren.WrenScript->CallInit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,12 +121,21 @@ void Scene::OnExit()
|
||||
PhysicsManager::Get()->Reset();
|
||||
|
||||
// destroy scripts.
|
||||
auto entities = m_Registry.view<WrenScriptComponent>();
|
||||
for (auto& e : entities)
|
||||
{
|
||||
m_Registry.view<NativeScriptComponent>().each([=](auto entity, auto& nsc)
|
||||
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
||||
|
||||
if (wren.WrenScript != nullptr)
|
||||
{
|
||||
nsc.Instance->OnDestroy();
|
||||
});
|
||||
wren.WrenScript->CallExit();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ScriptingEngine::Close();
|
||||
}
|
||||
|
||||
// update entities and some components.
|
||||
@@ -129,6 +149,16 @@ void Scene::Update(Timestep ts)
|
||||
});
|
||||
}
|
||||
|
||||
// destroy scripts.
|
||||
auto entities = m_Registry.view<WrenScriptComponent>();
|
||||
for (auto& e : entities)
|
||||
{
|
||||
WrenScriptComponent& wren = entities.get<WrenScriptComponent>(e);
|
||||
|
||||
if (wren.WrenScript != nullptr)
|
||||
wren.WrenScript->CallUpdate(ts);
|
||||
}
|
||||
|
||||
// Update rigidbodies
|
||||
PhysicsManager::Get()->Step(ts);
|
||||
|
||||
@@ -618,12 +648,14 @@ bool Scene::SaveAs(const std::string& path)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Scene::ReloadInterfaces()
|
||||
{
|
||||
for (auto& i : m_Interfaces)
|
||||
i->Reload();
|
||||
}
|
||||
|
||||
|
||||
void Scene::AddInterface(Ref<UI::UserInterface> interface)
|
||||
{
|
||||
this->m_Interfaces.push_back(interface);
|
||||
@@ -643,7 +675,6 @@ json Scene::Serialize()
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Scene::Deserialize(const std::string& str)
|
||||
{
|
||||
if (str == "")
|
||||
@@ -675,5 +706,6 @@ bool Scene::Deserialize(const std::string& str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,6 @@ namespace ScriptAPI
|
||||
class EngineModule : public ScriptModule
|
||||
{
|
||||
std::string ModuleName = "Engine";
|
||||
std::string WrenAPI = "class Engine { \n"
|
||||
"foreign static Log(msg) \n"
|
||||
"}"
|
||||
"";
|
||||
|
||||
std::string GetModuleName() override
|
||||
{
|
||||
@@ -24,7 +20,6 @@ namespace ScriptAPI
|
||||
void RegisterModule(WrenVM* vm) override
|
||||
{
|
||||
RegisterMethod("Log(_)", (void*)Log);
|
||||
WrenInterpretResult result = wrenInterpret(vm, "main", WrenAPI.c_str());
|
||||
}
|
||||
|
||||
static void Log(WrenVM* vm)
|
||||
@@ -33,6 +28,4 @@ namespace ScriptAPI
|
||||
Logger::Log(msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
38
Nuake/src/Scripting/Modules/EntityModule.h
Normal file
38
Nuake/src/Scripting/Modules/EntityModule.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "wren.h"
|
||||
#include <string>
|
||||
#include <src/Core/Logger.h>
|
||||
#include "ScriptModule.h"
|
||||
#include <iostream>
|
||||
#include <wren.h>
|
||||
|
||||
namespace ScriptAPI
|
||||
{
|
||||
class EngineModule : public ScriptModule
|
||||
{
|
||||
std::string ModuleName = "Engine";
|
||||
std::string WrenAPI = "class Engine { \n"
|
||||
"foreign static Log(msg) \n"
|
||||
"}"
|
||||
"";
|
||||
|
||||
std::string GetModuleName() override
|
||||
{
|
||||
return "Engine";
|
||||
}
|
||||
|
||||
void RegisterModule(WrenVM* vm) override
|
||||
{
|
||||
RegisterMethod("Log(_)", (void*)Log);
|
||||
WrenInterpretResult result = wrenInterpret(vm, "main", WrenAPI.c_str());
|
||||
}
|
||||
|
||||
static void Log(WrenVM* vm)
|
||||
{
|
||||
std::string msg = wrenGetSlotString(vm, 1);
|
||||
Logger::Log(msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
105
Nuake/src/Scripting/Modules/InputModule.h
Normal file
105
Nuake/src/Scripting/Modules/InputModule.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
#include "wren.h"
|
||||
#include <string>
|
||||
#include <src/Core/Logger.h>
|
||||
#include "ScriptModule.h"
|
||||
#include <iostream>
|
||||
#include <wren.h>
|
||||
#include "../Core/Maths.h"
|
||||
#include "../Core/Input.h"
|
||||
|
||||
namespace ScriptAPI
|
||||
{
|
||||
class InputModule : public ScriptModule
|
||||
{
|
||||
std::string GetModuleName() override
|
||||
{
|
||||
return "Input";
|
||||
}
|
||||
|
||||
void RegisterModule(WrenVM* vm) override
|
||||
{
|
||||
RegisterMethod("GetMouseX()", GetMouseX);
|
||||
RegisterMethod("GetMouseY()", (void*)GetMouseY);
|
||||
|
||||
RegisterMethod("IsKeyDown_(_)", (void*)IsKeyDown);
|
||||
RegisterMethod("IsKeyPressed_(_)", (void*)IsKeyPressed);
|
||||
RegisterMethod("IsKeyReleased_(_)", (void*)IsKeyReleased);
|
||||
|
||||
RegisterMethod("IsMouseButtonDown_(_)", (void*)IsMouseButtonDown);
|
||||
RegisterMethod("IsMouseButtonPressed_(_)", (void*)IsMouseButtonPressed);
|
||||
RegisterMethod("IsMouseButtonReleased_(_)", (void*)IsMouseButtonReleased);
|
||||
|
||||
RegisterMethod("HideMouse()", (void*)HideMouse);
|
||||
RegisterMethod("ShowMouse()", (void*)ShowMouse);
|
||||
RegisterMethod("IsMouseHidden()", (void*)IsMouseHidden);
|
||||
}
|
||||
|
||||
static void GetMouseX(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotDouble(vm, 0, Input::GetMouseX());
|
||||
}
|
||||
|
||||
static void GetMouseY(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotDouble(vm, 0, Input::GetMouseY());
|
||||
}
|
||||
|
||||
static void IsMouseButtonDown(WrenVM* vm)
|
||||
{
|
||||
int key = wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsMouseButtonDown(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void IsMouseButtonPressed(WrenVM* vm)
|
||||
{
|
||||
int key = (int)wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsMouseButtonPressed(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void IsMouseButtonReleased(WrenVM* vm)
|
||||
{
|
||||
int key = wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsMouseButtonReleased(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void IsKeyDown(WrenVM* vm)
|
||||
{
|
||||
int key = wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsKeyDown(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void IsKeyPressed(WrenVM* vm)
|
||||
{
|
||||
int key = wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsKeyPressed(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void IsKeyReleased(WrenVM* vm)
|
||||
{
|
||||
int key = wrenGetSlotDouble(vm, 1);
|
||||
bool result = Input::IsKeyReleased(key);
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
|
||||
static void HideMouse(WrenVM* vm)
|
||||
{
|
||||
Input::HideMouse();
|
||||
}
|
||||
|
||||
static void ShowMouse(WrenVM* vm)
|
||||
{
|
||||
Input::ShowMouse();
|
||||
}
|
||||
|
||||
static void IsMouseHidden(WrenVM* vm)
|
||||
{
|
||||
wrenSetSlotBool(vm, 0, Input::IsMouseHidden());
|
||||
}
|
||||
};
|
||||
}
|
||||
39
Nuake/src/Scripting/Modules/MathModule.h
Normal file
39
Nuake/src/Scripting/Modules/MathModule.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "wren.h"
|
||||
#include <string>
|
||||
#include <src/Core/Logger.h>
|
||||
#include "ScriptModule.h"
|
||||
#include <iostream>
|
||||
#include <wren.h>
|
||||
#include "../Core/Maths.h"
|
||||
|
||||
namespace ScriptAPI
|
||||
{
|
||||
class MathModule : public ScriptModule
|
||||
{
|
||||
std::string ModuleName = "Math";
|
||||
|
||||
|
||||
std::string GetModuleName() override
|
||||
{
|
||||
return "Math";
|
||||
}
|
||||
|
||||
void RegisterModule(WrenVM* vm) override
|
||||
{
|
||||
RegisterMethod("Sqrt_(_,_,_)", (void*)Sqrt);
|
||||
|
||||
}
|
||||
|
||||
static void Sqrt(WrenVM* vm)
|
||||
{
|
||||
float x = wrenGetSlotDouble(vm, 1);
|
||||
float y = wrenGetSlotDouble(vm, 2);
|
||||
float z = wrenGetSlotDouble(vm, 3);
|
||||
float result = glm::sqrt((x * x) + (y * y) + (z * z));
|
||||
wrenSetSlotDouble(vm, 0, result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <src/Scene/Entities/Components/QuakeMap.h>
|
||||
#include <src/Scene/Entities/Components/CameraComponent.h>
|
||||
#include <src/Scene/Entities/Components/RigidbodyComponent.h>
|
||||
#include <src/Scene/Entities/Components/CharacterControllerComponent.h>
|
||||
|
||||
namespace ScriptAPI
|
||||
{
|
||||
@@ -28,6 +29,12 @@ namespace ScriptAPI
|
||||
{
|
||||
RegisterMethod("GetEntityID(_)", (void*)GetEntity);
|
||||
RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent);
|
||||
RegisterMethod("SetLightIntensity_(_,_)", (void*)SetLightIntensity);
|
||||
RegisterMethod("GetLightIntensity_(_)", (void*)GetLightIntensity);
|
||||
RegisterMethod("SetCameraDirection_(_,_,_,_)", (void*)SetCameraDirection);
|
||||
RegisterMethod("GetCameraDirection_(_)", (void*)GetCameraDirection);
|
||||
RegisterMethod("GetCameraRight_(_)", (void*)GetCameraRight);
|
||||
RegisterMethod("MoveAndSlide_(_,_,_,_)", (void*)MoveAndSlide);
|
||||
}
|
||||
|
||||
static void GetEntity(WrenVM* vm)
|
||||
@@ -74,5 +81,96 @@ namespace ScriptAPI
|
||||
wrenSetSlotBool(vm, 0, result);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetLightIntensity(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float intensity = wrenGetSlotDouble(vm, 2);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& light = ent.GetComponent<LightComponent>();
|
||||
light.Strength = intensity;
|
||||
}
|
||||
|
||||
static void GetLightIntensity(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float intensity = wrenGetSlotDouble(vm, 2);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& light = ent.GetComponent<LightComponent>();
|
||||
wrenSetSlotDouble(vm, 0, light.Strength);
|
||||
}
|
||||
|
||||
static void SetCameraDirection(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float x = wrenGetSlotDouble(vm, 2);
|
||||
float y = wrenGetSlotDouble(vm, 3);
|
||||
float z = wrenGetSlotDouble(vm, 4);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
cam.CameraInstance->SetDirection(Vector3(x, y, z));
|
||||
}
|
||||
|
||||
static void GetCameraDirection(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
|
||||
Vector3 dir = cam.CameraInstance->GetDirection();
|
||||
|
||||
wrenEnsureSlots(vm, 4);
|
||||
|
||||
// set the slots
|
||||
// Fill the list
|
||||
wrenSetSlotNewList(vm, 0);
|
||||
wrenSetSlotDouble(vm, 1, dir.x);
|
||||
wrenSetSlotDouble(vm, 2, dir.y);
|
||||
wrenSetSlotDouble(vm, 3, dir.z);
|
||||
|
||||
wrenInsertInList(vm, 0, -1, 1);
|
||||
wrenInsertInList(vm, 0, -1, 2);
|
||||
wrenInsertInList(vm, 0, -1, 3);
|
||||
}
|
||||
|
||||
static void GetCameraRight(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
|
||||
auto& cam = ent.GetComponent<CameraComponent>();
|
||||
|
||||
Vector3 right = cam.CameraInstance->cameraRight;
|
||||
|
||||
// set the slots
|
||||
wrenSetSlotDouble(vm, 1, right.x);
|
||||
wrenSetSlotDouble(vm, 2, right.y);
|
||||
wrenSetSlotDouble(vm, 3, right.z);
|
||||
|
||||
// Fill the list
|
||||
wrenSetSlotNewList(vm, 0);
|
||||
wrenInsertInList(vm, 0, 0, 1);
|
||||
wrenInsertInList(vm, 0, 1, 2);
|
||||
wrenInsertInList(vm, 0, 2, 3);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void MoveAndSlide(WrenVM* vm)
|
||||
{
|
||||
int handle = wrenGetSlotDouble(vm, 1);
|
||||
float x = wrenGetSlotDouble(vm, 2);
|
||||
float y = wrenGetSlotDouble(vm, 3);
|
||||
float z = wrenGetSlotDouble(vm, 4);
|
||||
|
||||
Entity ent = Entity((entt::entity)handle, Engine::GetCurrentScene().get());
|
||||
auto& characterController = ent.GetComponent<CharacterControllerComponent>();
|
||||
characterController.CharacterController->MoveAndSlide(Vector3(x, y, z));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,9 @@
|
||||
#include <src/Scripting/Modules/ScriptModule.h>
|
||||
#include <src/Scripting/Modules/EngineModule.h>
|
||||
#include <src/Scripting/Modules/SceneModule.h>
|
||||
#include <src/Scripting/Modules/MathModule.h>
|
||||
#include <src/Scripting/Modules/InputModule.h>
|
||||
|
||||
WrenVM* ScriptingEngine::m_WrenVM;
|
||||
|
||||
|
||||
@@ -37,11 +40,25 @@ void writeFn(WrenVM* vm, const char* text) {
|
||||
printf("%s", text);
|
||||
}
|
||||
|
||||
bool hasEnding(std::string const& fullString, std::string const& ending) {
|
||||
if (fullString.length() >= ending.length()) {
|
||||
return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) {
|
||||
WrenLoadModuleResult result = { 0 };
|
||||
std::string str = FileSystem::ReadFile("resources/" + std::string(name) + ".wren", true);
|
||||
|
||||
std::string path = "resources/" + std::string(name);
|
||||
if(!hasEnding(path, ".wren"))
|
||||
path += ".wren";
|
||||
|
||||
std::string str = FileSystem::ReadFile(path, true);
|
||||
char* c = strcpy(new char[str.length() + 1], str.c_str());
|
||||
|
||||
result.source = c;
|
||||
return result;
|
||||
}
|
||||
@@ -91,6 +108,10 @@ void ScriptingEngine::Init()
|
||||
RegisterModule(engineModule);
|
||||
Ref<ScriptAPI::SceneModule> sceneModule = CreateRef<ScriptAPI::SceneModule>();
|
||||
RegisterModule(sceneModule);
|
||||
Ref<ScriptAPI::MathModule> mathModule = CreateRef<ScriptAPI::MathModule>();
|
||||
RegisterModule(mathModule);
|
||||
Ref<ScriptAPI::InputModule> inputModule = CreateRef<ScriptAPI::InputModule> ();
|
||||
RegisterModule(inputModule);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
#include "WrenScript.h"
|
||||
#include "../Core/FileSystem.h"
|
||||
#include <src/Vendors/wren/src/include/wren.h>
|
||||
WrenScript::WrenScript(const std::string& path, const std::string& mod)
|
||||
{
|
||||
|
||||
WrenScript::WrenScript(const std::string& path, const std::string& mod, bool isEntity)
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
|
||||
|
||||
// Import statement
|
||||
std::string source = "import \"" + path + "\" for " + mod;
|
||||
|
||||
// Import file as module
|
||||
wrenInterpret(vm, "main", source.c_str());
|
||||
|
||||
// Get handle to class
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "main", mod.c_str(), 0);
|
||||
WrenHandle* classHandle = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
// Call the constructor
|
||||
WrenHandle* constructHandle = wrenMakeCallHandle(vm, "new()");
|
||||
wrenCall(vm, constructHandle);
|
||||
|
||||
// Retreive value of constructor
|
||||
this->m_Instance = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
// Create handles to the instance methods.
|
||||
this->m_OnInitHandle = wrenMakeCallHandle(vm, "init()");
|
||||
this->m_OnUpdateHandle = wrenMakeCallHandle(vm, "update(_)");
|
||||
this->m_OnExitHandle = wrenMakeCallHandle(vm, "exit()");
|
||||
|
||||
if (isEntity)
|
||||
this->m_SetEntityIDHandle = wrenMakeCallHandle(vm, "SetEntityId(_)");
|
||||
}
|
||||
|
||||
void WrenScript::CallInit()
|
||||
@@ -26,7 +42,6 @@ void WrenScript::CallInit()
|
||||
|
||||
void WrenScript::CallUpdate(float timestep)
|
||||
{
|
||||
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenEnsureSlots(vm, 2);
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
@@ -37,6 +52,7 @@ void WrenScript::CallUpdate(float timestep)
|
||||
void WrenScript::CallExit()
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
WrenInterpretResult result = wrenCall(vm, this->m_OnExitHandle);
|
||||
}
|
||||
@@ -56,7 +72,16 @@ void WrenScript::CallMethod(const std::string& signature)
|
||||
// Not found. maybe try to register it?
|
||||
if (methods.find(signature) == methods.end())
|
||||
return;
|
||||
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
WrenHandle* handle = methods[signature];
|
||||
WrenInterpretResult result = wrenCall(vm, handle);
|
||||
}
|
||||
|
||||
void WrenScript::SetScriptableEntityID(int id)
|
||||
{
|
||||
WrenVM* vm = ScriptingEngine::GetWrenVM();
|
||||
wrenSetSlotHandle(vm, 0, this->m_Instance);
|
||||
wrenSetSlotDouble(vm, 1, id);
|
||||
WrenInterpretResult result = wrenCall(vm, this->m_SetEntityIDHandle);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,9 @@ public:
|
||||
WrenHandle* m_OnInitHandle;
|
||||
WrenHandle* m_OnUpdateHandle;
|
||||
WrenHandle* m_OnExitHandle;
|
||||
WrenHandle* m_SetEntityIDHandle;
|
||||
|
||||
WrenScript(const std::string& path, const std::string& mod);
|
||||
WrenScript(const std::string& path, const std::string& mod, bool isEntity = false);
|
||||
|
||||
void CallInit();
|
||||
void CallUpdate(float timestep);
|
||||
@@ -21,4 +22,6 @@ public:
|
||||
|
||||
void RegisterMethod(const std::string& signature);
|
||||
void CallMethod(const std::string& signature);
|
||||
|
||||
void SetScriptableEntityID(int id);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "InterfaceParser.h"
|
||||
|
||||
#include "Styling/Stylesheet.h"
|
||||
Ref<Canvas> InterfaceParser::Root = CreateRef<Canvas>();
|
||||
|
||||
void InterfaceParser::Iterate(const pugi::xml_node& xml_node, Ref<Node> node, int depth)
|
||||
@@ -271,6 +271,11 @@ Ref<Canvas> InterfaceParser::CreateCanvas(const pugi::xml_node& xml_node)
|
||||
std::string module = s[1];
|
||||
node->Script = ScriptingEngine::RegisterScript(path, module);
|
||||
}
|
||||
if (name == "stylesheet")
|
||||
{
|
||||
std::string path = a.value();
|
||||
node->StyleSheet = UI::StyleSheet::New(path);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include "../Core/Core.h"
|
||||
#include "../Scripting/WrenScript.h"
|
||||
#include <map>
|
||||
#include "../Styling/Stylesheet.h"
|
||||
|
||||
// Base container for UI.
|
||||
class Canvas : public Node
|
||||
{
|
||||
@@ -11,5 +13,7 @@ private:
|
||||
|
||||
public:
|
||||
Ref<WrenScript> Script;
|
||||
Ref<UI::StyleSheet> StyleSheet;
|
||||
|
||||
Canvas();
|
||||
};
|
||||
@@ -1,18 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "katana-parser/katana.h"
|
||||
#include "../Core/FileSystem.h"
|
||||
#include "../Core/Logger.h"
|
||||
#include "../Core/Core.h"
|
||||
#include "Style.h"
|
||||
|
||||
#include "katana-parser/katana.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "../Nodes/Node.h"
|
||||
#include <src/UI/Styling/StyleSheetParser.h>
|
||||
#include <regex>
|
||||
#include <regex>
|
||||
#include <src/UI/InterfaceParser.h>
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
namespace UI
|
||||
{
|
||||
class StyleSheet
|
||||
@@ -24,7 +20,20 @@ namespace UI
|
||||
public:
|
||||
std::string Path;
|
||||
static Ref<StyleSheet> New(const std::string& path);
|
||||
std::vector<std::string> Split(std::string const& str, const char delim)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
size_t start;
|
||||
size_t end = 0;
|
||||
|
||||
while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
|
||||
{
|
||||
end = str.find(delim, start);
|
||||
result.push_back(str.substr(start, end - start));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
void AddStyleGroup(std::string selector, Ref<StyleGroup> group)
|
||||
{
|
||||
Styles[selector] = group;
|
||||
@@ -90,7 +99,7 @@ namespace UI
|
||||
std::smatch match_value;
|
||||
Layout::LayoutVec4 result;
|
||||
|
||||
std::vector<std::string> splits = InterfaceParser::split(value, ' ');
|
||||
std::vector<std::string> splits = Split(value, ' ');
|
||||
int idx = 0;
|
||||
for (auto& s : splits)
|
||||
{
|
||||
@@ -245,7 +254,6 @@ namespace UI
|
||||
KatanaArray errors = Data->errors;
|
||||
return false;
|
||||
}
|
||||
katana_dump_output(Data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,11 +14,8 @@ namespace UI
|
||||
m_Name = name;
|
||||
|
||||
font = FontLoader::LoadFont("resources/Fonts/RobotoMono-Regular.ttf");
|
||||
|
||||
m_Stylesheet = StyleSheet::New("/Interface\\Testing.css");
|
||||
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
|
||||
|
||||
if (!Root)
|
||||
{
|
||||
Logger::Log("Failed to generate interface structure");
|
||||
@@ -38,7 +35,6 @@ namespace UI
|
||||
|
||||
void UserInterface::Reload()
|
||||
{
|
||||
m_Stylesheet = StyleSheet::New("/Interface\\Testing.css");
|
||||
Root = InterfaceParser::Parse("resources/Interface/Testing.interface");
|
||||
if (!Root)
|
||||
{
|
||||
@@ -67,8 +63,8 @@ namespace UI
|
||||
Root->YogaNode = yoga_root;
|
||||
|
||||
for (auto& g : Root->GetGroups())
|
||||
if (m_Stylesheet->HasStyleGroup(g))
|
||||
Root->ApplyStyle(m_Stylesheet->GetStyleGroup(g));
|
||||
if (Root->StyleSheet->HasStyleGroup(g))
|
||||
Root->ApplyStyle(Root->StyleSheet->GetStyleGroup(g));
|
||||
Root->SetYogaLayout();
|
||||
CreateYogaLayoutRecursive(Root, yoga_root);
|
||||
}
|
||||
@@ -85,8 +81,8 @@ namespace UI
|
||||
n->YogaNode = newYogaNode;
|
||||
|
||||
for (auto& g : n->GetGroups())
|
||||
if (m_Stylesheet->HasStyleGroup(g))
|
||||
n->ApplyStyle(m_Stylesheet->GetStyleGroup(g));
|
||||
if (Root->StyleSheet->HasStyleGroup(g))
|
||||
n->ApplyStyle(Root->StyleSheet->GetStyleGroup(g));
|
||||
|
||||
n->SetYogaLayout();
|
||||
YGNodeInsertChild(yoga_node, newYogaNode, index);
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace UI
|
||||
Ref<FrameBuffer> m_Framebuffer; // Texture of the interface.
|
||||
std::string m_Name;
|
||||
Ref<Canvas> Root;
|
||||
Ref<StyleSheet> m_Stylesheet;
|
||||
YGConfigRef yoga_config;
|
||||
YGNodeRef yoga_root;
|
||||
public:
|
||||
|
||||
20
Nuake/src/Vendors/msdf-atlas-gen/.gitignore
vendored
Normal file
20
Nuake/src/Vendors/msdf-atlas-gen/.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Debug/
|
||||
Release/
|
||||
Debug Library/
|
||||
Release Library/
|
||||
x86/
|
||||
x64/
|
||||
*.exe
|
||||
*.user
|
||||
*.sdf
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.iobj
|
||||
*.suo
|
||||
*.VC.opendb
|
||||
*.VC.db
|
||||
bin/msdf-atlas-gen
|
||||
bin/*.lib
|
||||
output.png
|
||||
out/
|
||||
build/
|
||||
6
Nuake/src/Vendors/msdf-atlas-gen/.gitmodules
vendored
Normal file
6
Nuake/src/Vendors/msdf-atlas-gen/.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "msdfgen"]
|
||||
path = msdfgen
|
||||
url = https://github.com/Chlumsky/msdfgen
|
||||
[submodule "artery-font-format"]
|
||||
path = artery-font-format
|
||||
url = https://github.com/Chlumsky/artery-font-format
|
||||
42
Nuake/src/Vendors/msdf-atlas-gen/AtlasGenerator.h
Normal file
42
Nuake/src/Vendors/msdf-atlas-gen/AtlasGenerator.h
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "msdfgen.h"
|
||||
#include "Remap.h"
|
||||
#include "GlyphGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
namespace {
|
||||
|
||||
/** Prototype of an atlas generator class.
|
||||
* An atlas generator maintains the atlas bitmap (AtlasStorage) and its layout and facilitates
|
||||
* generation of bitmap representation of glyphs. The layout of the atlas is given by the caller.
|
||||
*/
|
||||
class AtlasGenerator {
|
||||
|
||||
public:
|
||||
AtlasGenerator();
|
||||
AtlasGenerator(int width, int height);
|
||||
/// Generates bitmap representation for the supplied array of glyphs
|
||||
void generate(const GlyphGeometry *glyphs, int count);
|
||||
/// Resizes the atlas and rearranges the generated pixels according to the remapping array
|
||||
void rearrange(int width, int height, const Remap *remapping, int count);
|
||||
/// Resizes the atlas and keeps the generated pixels in place
|
||||
void resize(int width, int height);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/// Configuration of signed distance field generator
|
||||
struct GeneratorAttributes {
|
||||
msdfgen::MSDFGeneratorConfig config;
|
||||
bool scanlinePass = false;
|
||||
};
|
||||
|
||||
/// A function that generates the bitmap for a single glyph
|
||||
template <typename T, int N>
|
||||
using GeneratorFunction = void (*)(const msdfgen::BitmapRef<T, N> &, const GlyphGeometry &, const GeneratorAttributes &);
|
||||
|
||||
}
|
||||
37
Nuake/src/Vendors/msdf-atlas-gen/AtlasStorage.h
Normal file
37
Nuake/src/Vendors/msdf-atlas-gen/AtlasStorage.h
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include "Remap.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
namespace {
|
||||
|
||||
/** Prototype of an atlas storage class.
|
||||
* An atlas storage physically holds the pixels of the atlas
|
||||
* and allows to read and write subsections represented as bitmaps.
|
||||
* Can be implemented using a simple bitmap (BitmapAtlasStorage),
|
||||
* as texture memory, or any other way.
|
||||
*/
|
||||
class AtlasStorage {
|
||||
|
||||
public:
|
||||
AtlasStorage();
|
||||
AtlasStorage(int width, int height);
|
||||
/// Creates a copy with different dimensions
|
||||
AtlasStorage(const AtlasStorage &orig, int width, int height);
|
||||
/// Creates a copy with different dimensions and rearranges the pixels according to the remapping array
|
||||
AtlasStorage(const AtlasStorage &orig, int width, int height, const Remap *remapping, int count);
|
||||
/// Stores a subsection at x, y into the atlas storage. May be implemented for only some T, N
|
||||
template <typename T, int N>
|
||||
void put(int x, int y, const msdfgen::BitmapConstRef<T, N> &subBitmap);
|
||||
/// Retrieves a subsection at x, y from the atlas storage. May be implemented for only some T, N
|
||||
template <typename T, int N>
|
||||
void get(int x, int y, const msdfgen::BitmapRef<T, N> &subBitmap) const;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
33
Nuake/src/Vendors/msdf-atlas-gen/BitmapAtlasStorage.h
Normal file
33
Nuake/src/Vendors/msdf-atlas-gen/BitmapAtlasStorage.h
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AtlasStorage.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// An implementation of AtlasStorage represented by a bitmap in memory (msdfgen::Bitmap)
|
||||
template <typename T, int N>
|
||||
class BitmapAtlasStorage {
|
||||
|
||||
public:
|
||||
BitmapAtlasStorage();
|
||||
BitmapAtlasStorage(int width, int height);
|
||||
explicit BitmapAtlasStorage(const msdfgen::BitmapConstRef<T, N> &bitmap);
|
||||
explicit BitmapAtlasStorage(msdfgen::Bitmap<T, N> &&bitmap);
|
||||
BitmapAtlasStorage(const BitmapAtlasStorage<T, N> &orig, int width, int height);
|
||||
BitmapAtlasStorage(const BitmapAtlasStorage<T, N> &orig, int width, int height, const Remap *remapping, int count);
|
||||
operator msdfgen::BitmapConstRef<T, N>() const;
|
||||
operator msdfgen::BitmapRef<T, N>();
|
||||
operator msdfgen::Bitmap<T, N>() &&;
|
||||
template <typename S>
|
||||
void put(int x, int y, const msdfgen::BitmapConstRef<S, N> &subBitmap);
|
||||
void get(int x, int y, const msdfgen::BitmapRef<T, N> &subBitmap) const;
|
||||
|
||||
private:
|
||||
msdfgen::Bitmap<T, N> bitmap;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "BitmapAtlasStorage.hpp"
|
||||
65
Nuake/src/Vendors/msdf-atlas-gen/BitmapAtlasStorage.hpp
Normal file
65
Nuake/src/Vendors/msdf-atlas-gen/BitmapAtlasStorage.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
#include "BitmapAtlasStorage.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include "bitmap-blit.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage() { }
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage(int width, int height) : bitmap(width, height) {
|
||||
memset((T *) bitmap, 0, sizeof(T)*N*width*height);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage(const msdfgen::BitmapConstRef<T, N> &bitmap) : bitmap(bitmap) { }
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage(msdfgen::Bitmap<T, N> &&bitmap) : bitmap((msdfgen::Bitmap<T, N> &&) bitmap) { }
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage(const BitmapAtlasStorage<T, N> &orig, int width, int height) : bitmap(width, height) {
|
||||
memset((T *) bitmap, 0, sizeof(T)*N*width*height);
|
||||
blit(bitmap, orig.bitmap, 0, 0, 0, 0, std::min(width, orig.bitmap.width()), std::min(height, orig.bitmap.height()));
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::BitmapAtlasStorage(const BitmapAtlasStorage<T, N> &orig, int width, int height, const Remap *remapping, int count) : bitmap(width, height) {
|
||||
memset((T *) bitmap, 0, sizeof(T)*N*width*height);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const Remap &remap = remapping[i];
|
||||
blit(bitmap, orig.bitmap, remap.target.x, remap.target.y, remap.source.x, remap.source.y, remap.width, remap.height);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::operator msdfgen::BitmapConstRef<T, N>() const {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::operator msdfgen::BitmapRef<T, N>() {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
BitmapAtlasStorage<T, N>::operator msdfgen::Bitmap<T, N>() && {
|
||||
return (msdfgen::Bitmap<T, N> &&) bitmap;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
template <typename S>
|
||||
void BitmapAtlasStorage<T, N>::put(int x, int y, const msdfgen::BitmapConstRef<S, N> &subBitmap) {
|
||||
blit(bitmap, subBitmap, x, y, 0, 0, subBitmap.width, subBitmap.height);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void BitmapAtlasStorage<T, N>::get(int x, int y, const msdfgen::BitmapRef<T, N> &subBitmap) const {
|
||||
blit(subBitmap, bitmap, 0, 0, x, y, subBitmap.width, subBitmap.height);
|
||||
}
|
||||
|
||||
}
|
||||
26
Nuake/src/Vendors/msdf-atlas-gen/CHANGELOG.md
Normal file
26
Nuake/src/Vendors/msdf-atlas-gen/CHANGELOG.md
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
## Version 1.2 (2021-05-29)
|
||||
|
||||
- Updated to MSDFgen 1.9.
|
||||
- Multiple fonts or font sizes can now be compiled into a single atlas.
|
||||
- Added `-yorigin` option to choose if Y-coordinates increase from bottom to top or from top to bottom.
|
||||
- Added `-coloringstrategy` option to select MSDF edge coloring heuristic.
|
||||
- Shadron preview now properly loads floating-point image outputs in full range mode.
|
||||
|
||||
## Version 1.1 (2020-10-18)
|
||||
|
||||
- Updated to MSDFgen 1.8.
|
||||
- Glyph geometry is now preprocessed by Skia to resolve irregularities which were previously unsupported and caused artifacts.
|
||||
- The scanline pass and overlapping contour mode is made obsolete by this step and has been disabled by default. The preprocess step can be disabled by the new `-nopreprocess` switch and the former enabled by `-scanline` and `-overlap` respectively.
|
||||
- The project can be built without the Skia library, forgoing the geometry preprocessing feature. This is controlled by the macro definition `MSDFGEN_USE_SKIA`.
|
||||
- Glyphs can now also be loaded by glyph index rather than Unicode values. In the standalone version, a set of glyphs can be passed by `-glyphset` in place of `-charset`.
|
||||
- Glyphs not present in the font should now be correctly skipped instead of producing a placeholder symbol.
|
||||
- Added `-threads` argument to set the number of concurrent threads used during distance field generation.
|
||||
|
||||
### Version 1.0.1 (2020-03-09)
|
||||
|
||||
- Updated to MSDFgen 1.7.1.
|
||||
|
||||
## Version 1.0 (2020-03-08)
|
||||
|
||||
- Initial release.
|
||||
39
Nuake/src/Vendors/msdf-atlas-gen/Charset.cpp
Normal file
39
Nuake/src/Vendors/msdf-atlas-gen/Charset.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
#include "Charset.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
static Charset createAsciiCharset() {
|
||||
Charset ascii;
|
||||
for (unicode_t cp = 0x20; cp < 0x7f; ++cp)
|
||||
ascii.add(cp);
|
||||
return ascii;
|
||||
}
|
||||
|
||||
const Charset Charset::ASCII = createAsciiCharset();
|
||||
|
||||
void Charset::add(unicode_t cp) {
|
||||
codepoints.insert(cp);
|
||||
}
|
||||
|
||||
void Charset::remove(unicode_t cp) {
|
||||
codepoints.erase(cp);
|
||||
}
|
||||
|
||||
size_t Charset::size() const {
|
||||
return codepoints.size();
|
||||
}
|
||||
|
||||
bool Charset::empty() const {
|
||||
return codepoints.empty();
|
||||
}
|
||||
|
||||
std::set<unicode_t>::const_iterator Charset::begin() const {
|
||||
return codepoints.begin();
|
||||
}
|
||||
|
||||
std::set<unicode_t>::const_iterator Charset::end() const {
|
||||
return codepoints.end();
|
||||
}
|
||||
|
||||
}
|
||||
35
Nuake/src/Vendors/msdf-atlas-gen/Charset.h
Normal file
35
Nuake/src/Vendors/msdf-atlas-gen/Charset.h
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
#include "types.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Represents a set of Unicode codepoints (characters)
|
||||
class Charset {
|
||||
|
||||
public:
|
||||
/// The set of the 95 printable ASCII characters
|
||||
static const Charset ASCII;
|
||||
|
||||
/// Adds a codepoint
|
||||
void add(unicode_t cp);
|
||||
/// Removes a codepoint
|
||||
void remove(unicode_t cp);
|
||||
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
std::set<unicode_t>::const_iterator begin() const;
|
||||
std::set<unicode_t>::const_iterator end() const;
|
||||
|
||||
/// Load character set from a text file with the correct syntax
|
||||
bool load(const char *filename, bool disableCharLiterals = false);
|
||||
|
||||
private:
|
||||
std::set<unicode_t> codepoints;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
43
Nuake/src/Vendors/msdf-atlas-gen/DynamicAtlas.h
Normal file
43
Nuake/src/Vendors/msdf-atlas-gen/DynamicAtlas.h
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RectanglePacker.h"
|
||||
#include "AtlasGenerator.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/**
|
||||
* This class can be used to produce a dynamic atlas to which more glyphs are added over time.
|
||||
* It takes care of laying out and enlarging the atlas as necessary and delegates the actual work
|
||||
* to the specified AtlasGenerator, which may e.g. do the work asynchronously.
|
||||
*/
|
||||
template <class AtlasGenerator>
|
||||
class DynamicAtlas {
|
||||
|
||||
public:
|
||||
DynamicAtlas();
|
||||
/// Creates with a configured generator. The generator must not contain any prior glyphs!
|
||||
explicit DynamicAtlas(AtlasGenerator &&generator);
|
||||
/// Adds a batch of glyphs. Adding more than one glyph at a time may improve packing efficiency
|
||||
void add(GlyphGeometry *glyphs, int count);
|
||||
/// Allows access to generator. Do not add glyphs to the generator directly!
|
||||
AtlasGenerator & atlasGenerator();
|
||||
const AtlasGenerator & atlasGenerator() const;
|
||||
|
||||
private:
|
||||
AtlasGenerator generator;
|
||||
RectanglePacker packer;
|
||||
int glyphCount;
|
||||
int side;
|
||||
std::vector<Rectangle> rectangles;
|
||||
std::vector<Remap> remapBuffer;
|
||||
int totalArea;
|
||||
GeneratorAttributes genAttribs;
|
||||
int padding;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "DynamicAtlas.hpp"
|
||||
69
Nuake/src/Vendors/msdf-atlas-gen/DynamicAtlas.hpp
Normal file
69
Nuake/src/Vendors/msdf-atlas-gen/DynamicAtlas.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
#include "DynamicAtlas.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
template <class AtlasGenerator>
|
||||
DynamicAtlas<AtlasGenerator>::DynamicAtlas() : glyphCount(0), side(0), totalArea(0), padding(0) { }
|
||||
|
||||
template <class AtlasGenerator>
|
||||
DynamicAtlas<AtlasGenerator>::DynamicAtlas(AtlasGenerator &&generator) : generator((AtlasGenerator &&) generator), glyphCount(0), side(0), totalArea(0), padding(0) { }
|
||||
|
||||
template <class AtlasGenerator>
|
||||
void DynamicAtlas<AtlasGenerator>::add(GlyphGeometry *glyphs, int count) {
|
||||
int start = rectangles.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (!glyphs[i].isWhitespace()) {
|
||||
int w, h;
|
||||
glyphs[i].getBoxSize(w, h);
|
||||
Rectangle rect = { 0, 0, w+padding, h+padding };
|
||||
rectangles.push_back(rect);
|
||||
Remap remapEntry = { };
|
||||
remapEntry.index = glyphCount+i;
|
||||
remapEntry.width = w;
|
||||
remapEntry.height = h;
|
||||
remapBuffer.push_back(remapEntry);
|
||||
totalArea += (w+padding)*(h+padding);
|
||||
}
|
||||
}
|
||||
if ((int) rectangles.size() > start) {
|
||||
int oldSide = side;
|
||||
int packerStart = start;
|
||||
while (packer.pack(rectangles.data()+packerStart, rectangles.size()-packerStart) > 0) {
|
||||
side = side+!side<<1;
|
||||
while (side*side < totalArea)
|
||||
side <<= 1;
|
||||
packer = RectanglePacker(side+padding, side+padding);
|
||||
packerStart = 0;
|
||||
}
|
||||
if (packerStart < start) {
|
||||
for (int i = 0; i < start; ++i) {
|
||||
Remap &remap = remapBuffer[i];
|
||||
remap.source = remap.target;
|
||||
remap.target.x = rectangles[i].x;
|
||||
remap.target.y = rectangles[i].y;
|
||||
}
|
||||
generator.rearrange(side, side, remapBuffer.data(), start);
|
||||
} else if (side != oldSide)
|
||||
generator.resize(side, side);
|
||||
for (int i = start; i < (int) rectangles.size(); ++i) {
|
||||
remapBuffer[i].target.x = rectangles[i].x;
|
||||
remapBuffer[i].target.y = rectangles[i].y;
|
||||
glyphs[remapBuffer[i].index-glyphCount].placeBox(rectangles[i].x, rectangles[i].y);
|
||||
}
|
||||
}
|
||||
generator.generate(glyphs, count, genAttribs);
|
||||
glyphCount += count;
|
||||
}
|
||||
|
||||
template <class AtlasGenerator>
|
||||
AtlasGenerator & DynamicAtlas<AtlasGenerator>::atlasGenerator() {
|
||||
return generator;
|
||||
}
|
||||
|
||||
template <class AtlasGenerator>
|
||||
const AtlasGenerator & DynamicAtlas<AtlasGenerator>::atlasGenerator() const {
|
||||
return generator;
|
||||
}
|
||||
|
||||
}
|
||||
185
Nuake/src/Vendors/msdf-atlas-gen/FontGeometry.cpp
Normal file
185
Nuake/src/Vendors/msdf-atlas-gen/FontGeometry.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
#include "FontGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
FontGeometry::GlyphRange::GlyphRange() : glyphs(), rangeStart(), rangeEnd() { }
|
||||
|
||||
FontGeometry::GlyphRange::GlyphRange(const std::vector<GlyphGeometry> *glyphs, size_t rangeStart, size_t rangeEnd) : glyphs(glyphs), rangeStart(rangeStart), rangeEnd(rangeEnd) { }
|
||||
|
||||
size_t FontGeometry::GlyphRange::size() const {
|
||||
return glyphs->size();
|
||||
}
|
||||
|
||||
bool FontGeometry::GlyphRange::empty() const {
|
||||
return glyphs->empty();
|
||||
}
|
||||
|
||||
const GlyphGeometry * FontGeometry::GlyphRange::begin() const {
|
||||
return glyphs->data()+rangeStart;
|
||||
}
|
||||
|
||||
const GlyphGeometry * FontGeometry::GlyphRange::end() const {
|
||||
return glyphs->data()+rangeEnd;
|
||||
}
|
||||
|
||||
FontGeometry::FontGeometry() : geometryScale(1), metrics(), preferredIdentifierType(GlyphIdentifierType::UNICODE_CODEPOINT), glyphs(&ownGlyphs), rangeStart(glyphs->size()), rangeEnd(glyphs->size()) { }
|
||||
|
||||
FontGeometry::FontGeometry(std::vector<GlyphGeometry> *glyphStorage) : geometryScale(1), metrics(), preferredIdentifierType(GlyphIdentifierType::UNICODE_CODEPOINT), glyphs(glyphStorage), rangeStart(glyphs->size()), rangeEnd(glyphs->size()) { }
|
||||
|
||||
int FontGeometry::loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry, bool enableKerning) {
|
||||
if (!(glyphs->size() == rangeEnd && loadMetrics(font, fontScale)))
|
||||
return -1;
|
||||
glyphs->reserve(glyphs->size()+glyphset.size());
|
||||
int loaded = 0;
|
||||
for (unicode_t index : glyphset) {
|
||||
GlyphGeometry glyph;
|
||||
if (glyph.load(font, geometryScale, msdfgen::GlyphIndex(index), preprocessGeometry)) {
|
||||
addGlyph((GlyphGeometry &&) glyph);
|
||||
++loaded;
|
||||
}
|
||||
}
|
||||
if (enableKerning)
|
||||
loadKerning(font);
|
||||
preferredIdentifierType = GlyphIdentifierType::GLYPH_INDEX;
|
||||
return loaded;
|
||||
}
|
||||
|
||||
int FontGeometry::loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry, bool enableKerning) {
|
||||
if (!(glyphs->size() == rangeEnd && loadMetrics(font, fontScale)))
|
||||
return -1;
|
||||
glyphs->reserve(glyphs->size()+charset.size());
|
||||
int loaded = 0;
|
||||
for (unicode_t cp : charset) {
|
||||
GlyphGeometry glyph;
|
||||
if (glyph.load(font, geometryScale, cp, preprocessGeometry)) {
|
||||
addGlyph((GlyphGeometry &&) glyph);
|
||||
++loaded;
|
||||
}
|
||||
}
|
||||
if (enableKerning)
|
||||
loadKerning(font);
|
||||
preferredIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool FontGeometry::loadMetrics(msdfgen::FontHandle *font, double fontScale) {
|
||||
if (!msdfgen::getFontMetrics(metrics, font))
|
||||
return false;
|
||||
if (metrics.emSize <= 0)
|
||||
metrics.emSize = MSDF_ATLAS_DEFAULT_EM_SIZE;
|
||||
geometryScale = fontScale/metrics.emSize;
|
||||
metrics.emSize *= geometryScale;
|
||||
metrics.ascenderY *= geometryScale;
|
||||
metrics.descenderY *= geometryScale;
|
||||
metrics.lineHeight *= geometryScale;
|
||||
metrics.underlineY *= geometryScale;
|
||||
metrics.underlineThickness *= geometryScale;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontGeometry::addGlyph(const GlyphGeometry &glyph) {
|
||||
if (glyphs->size() != rangeEnd)
|
||||
return false;
|
||||
glyphsByIndex.insert(std::make_pair(glyph.getIndex(), rangeEnd));
|
||||
if (glyph.getCodepoint())
|
||||
glyphsByCodepoint.insert(std::make_pair(glyph.getCodepoint(), rangeEnd));
|
||||
glyphs->push_back(glyph);
|
||||
++rangeEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontGeometry::addGlyph(GlyphGeometry &&glyph) {
|
||||
if (glyphs->size() != rangeEnd)
|
||||
return false;
|
||||
glyphsByIndex.insert(std::make_pair(glyph.getIndex(), rangeEnd));
|
||||
if (glyph.getCodepoint())
|
||||
glyphsByCodepoint.insert(std::make_pair(glyph.getCodepoint(), rangeEnd));
|
||||
glyphs->push_back((GlyphGeometry &&) glyph);
|
||||
++rangeEnd;
|
||||
return true;
|
||||
}
|
||||
|
||||
int FontGeometry::loadKerning(msdfgen::FontHandle *font) {
|
||||
int loaded = 0;
|
||||
for (size_t i = rangeStart; i < rangeEnd; ++i)
|
||||
for (size_t j = rangeStart; j < rangeEnd; ++j) {
|
||||
double advance;
|
||||
if (msdfgen::getKerning(advance, font, (*glyphs)[i].getGlyphIndex(), (*glyphs)[j].getGlyphIndex()) && advance) {
|
||||
kerning[std::make_pair<int, int>((*glyphs)[i].getIndex(), (*glyphs)[j].getIndex())] = geometryScale*advance;
|
||||
++loaded;
|
||||
}
|
||||
}
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void FontGeometry::setName(const char *name) {
|
||||
if (name)
|
||||
this->name = name;
|
||||
else
|
||||
this->name.clear();
|
||||
}
|
||||
|
||||
double FontGeometry::getGeometryScale() const {
|
||||
return geometryScale;
|
||||
}
|
||||
|
||||
const msdfgen::FontMetrics & FontGeometry::getMetrics() const {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
GlyphIdentifierType FontGeometry::getPreferredIdentifierType() const {
|
||||
return preferredIdentifierType;
|
||||
}
|
||||
|
||||
FontGeometry::GlyphRange FontGeometry::getGlyphs() const {
|
||||
return GlyphRange(glyphs, rangeStart, rangeEnd);
|
||||
}
|
||||
|
||||
const GlyphGeometry * FontGeometry::getGlyph(msdfgen::GlyphIndex index) const {
|
||||
std::map<int, size_t>::const_iterator it = glyphsByIndex.find(index.getIndex());
|
||||
if (it != glyphsByIndex.end())
|
||||
return &(*glyphs)[it->second];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GlyphGeometry * FontGeometry::getGlyph(unicode_t codepoint) const {
|
||||
std::map<unicode_t, size_t>::const_iterator it = glyphsByCodepoint.find(codepoint);
|
||||
if (it != glyphsByCodepoint.end())
|
||||
return &(*glyphs)[it->second];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool FontGeometry::getAdvance(double &advance, msdfgen::GlyphIndex index1, msdfgen::GlyphIndex index2) const {
|
||||
const GlyphGeometry *glyph1 = getGlyph(index1);
|
||||
if (!glyph1)
|
||||
return false;
|
||||
advance = glyph1->getAdvance();
|
||||
std::map<std::pair<int, int>, double>::const_iterator it = kerning.find(std::make_pair<int, int>(index1.getIndex(), index2.getIndex()));
|
||||
if (it != kerning.end())
|
||||
advance += it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FontGeometry::getAdvance(double &advance, unicode_t codepoint1, unicode_t codepoint2) const {
|
||||
const GlyphGeometry *glyph1, *glyph2;
|
||||
if (!((glyph1 = getGlyph(codepoint1)) && (glyph2 = getGlyph(codepoint2))))
|
||||
return false;
|
||||
advance = glyph1->getAdvance();
|
||||
std::map<std::pair<int, int>, double>::const_iterator it = kerning.find(std::make_pair<int, int>(glyph1->getIndex(), glyph2->getIndex()));
|
||||
if (it != kerning.end())
|
||||
advance += it->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::map<std::pair<int, int>, double> & FontGeometry::getKerning() const {
|
||||
return kerning;
|
||||
}
|
||||
|
||||
const char * FontGeometry::getName() const {
|
||||
if (name.empty())
|
||||
return nullptr;
|
||||
return name.c_str();
|
||||
}
|
||||
|
||||
}
|
||||
86
Nuake/src/Vendors/msdf-atlas-gen/FontGeometry.h
Normal file
86
Nuake/src/Vendors/msdf-atlas-gen/FontGeometry.h
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <msdfgen.h>
|
||||
#include <msdfgen-ext.h>
|
||||
#include "types.h"
|
||||
#include "GlyphGeometry.h"
|
||||
#include "Charset.h"
|
||||
|
||||
#define MSDF_ATLAS_DEFAULT_EM_SIZE 32.0
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Represents the geometry of all glyphs of a given font or font variant
|
||||
class FontGeometry {
|
||||
|
||||
public:
|
||||
class GlyphRange {
|
||||
public:
|
||||
GlyphRange();
|
||||
GlyphRange(const std::vector<GlyphGeometry> *glyphs, size_t rangeStart, size_t rangeEnd);
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
const GlyphGeometry * begin() const;
|
||||
const GlyphGeometry * end() const;
|
||||
private:
|
||||
const std::vector<GlyphGeometry> *glyphs;
|
||||
size_t rangeStart, rangeEnd;
|
||||
};
|
||||
|
||||
FontGeometry();
|
||||
explicit FontGeometry(std::vector<GlyphGeometry> *glyphStorage);
|
||||
|
||||
/// Loads all glyphs in a glyphset (Charset elements are glyph indices), returns the number of successfully loaded glyphs
|
||||
int loadGlyphset(msdfgen::FontHandle *font, double fontScale, const Charset &glyphset, bool preprocessGeometry = true, bool enableKerning = true);
|
||||
/// Loads all glyphs in a charset (Charset elements are Unicode codepoints), returns the number of successfully loaded glyphs
|
||||
int loadCharset(msdfgen::FontHandle *font, double fontScale, const Charset &charset, bool preprocessGeometry = true, bool enableKerning = true);
|
||||
|
||||
/// Only loads font metrics and geometry scale from font
|
||||
bool loadMetrics(msdfgen::FontHandle *font, double fontScale);
|
||||
/// Adds a loaded glyph
|
||||
bool addGlyph(const GlyphGeometry &glyph);
|
||||
bool addGlyph(GlyphGeometry &&glyph);
|
||||
/// Loads kerning pairs for all glyphs that are currently present, returns the number of loaded kerning pairs
|
||||
int loadKerning(msdfgen::FontHandle *font);
|
||||
/// Sets a name to be associated with the font
|
||||
void setName(const char *name);
|
||||
|
||||
/// Returns the geometry scale to be used when loading glyphs
|
||||
double getGeometryScale() const;
|
||||
/// Returns the processed font metrics
|
||||
const msdfgen::FontMetrics & getMetrics() const;
|
||||
/// Returns the type of identifier that was used to load glyphs
|
||||
GlyphIdentifierType getPreferredIdentifierType() const;
|
||||
/// Returns the list of all glyphs
|
||||
GlyphRange getGlyphs() const;
|
||||
/// Finds a glyph by glyph index or Unicode codepoint, returns null if not found
|
||||
const GlyphGeometry * getGlyph(msdfgen::GlyphIndex index) const;
|
||||
const GlyphGeometry * getGlyph(unicode_t codepoint) const;
|
||||
/// Outputs the advance between two glyphs with kerning taken into consideration, returns false on failure
|
||||
bool getAdvance(double &advance, msdfgen::GlyphIndex index1, msdfgen::GlyphIndex index2) const;
|
||||
bool getAdvance(double &advance, unicode_t codepoint1, unicode_t codepoint2) const;
|
||||
/// Returns the complete mapping of kerning pairs (by glyph indices) and their respective advance values
|
||||
const std::map<std::pair<int, int>, double> & getKerning() const;
|
||||
/// Returns the name associated with the font or null if not set
|
||||
const char * getName() const;
|
||||
|
||||
private:
|
||||
double geometryScale;
|
||||
msdfgen::FontMetrics metrics;
|
||||
GlyphIdentifierType preferredIdentifierType;
|
||||
std::vector<GlyphGeometry> *glyphs;
|
||||
size_t rangeStart, rangeEnd;
|
||||
std::map<int, size_t> glyphsByIndex;
|
||||
std::map<unicode_t, size_t> glyphsByCodepoint;
|
||||
std::map<std::pair<int, int>, double> kerning;
|
||||
std::vector<GlyphGeometry> ownGlyphs;
|
||||
std::string name;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
19
Nuake/src/Vendors/msdf-atlas-gen/GlyphBox.h
Normal file
19
Nuake/src/Vendors/msdf-atlas-gen/GlyphBox.h
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// The glyph box - its bounds in plane and atlas
|
||||
struct GlyphBox {
|
||||
int index;
|
||||
double advance;
|
||||
struct {
|
||||
double l, b, r, t;
|
||||
} bounds;
|
||||
struct {
|
||||
int x, y, w, h;
|
||||
} rect;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
170
Nuake/src/Vendors/msdf-atlas-gen/GlyphGeometry.cpp
Normal file
170
Nuake/src/Vendors/msdf-atlas-gen/GlyphGeometry.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
|
||||
#include "GlyphGeometry.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <core/ShapeDistanceFinder.h>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
GlyphGeometry::GlyphGeometry() : index(), codepoint(), geometryScale(), bounds(), advance(), box() { }
|
||||
|
||||
bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry) {
|
||||
if (font && msdfgen::loadGlyph(shape, font, index, &advance) && shape.validate()) {
|
||||
this->index = index.getIndex();
|
||||
this->geometryScale = geometryScale;
|
||||
codepoint = 0;
|
||||
advance *= geometryScale;
|
||||
#ifdef MSDFGEN_USE_SKIA
|
||||
if (preprocessGeometry)
|
||||
msdfgen::resolveShapeGeometry(shape);
|
||||
#endif
|
||||
shape.normalize();
|
||||
bounds = shape.getBounds();
|
||||
#ifdef MSDFGEN_USE_SKIA
|
||||
if (!preprocessGeometry)
|
||||
#endif
|
||||
{
|
||||
// Determine if shape is winded incorrectly and reverse it in that case
|
||||
msdfgen::Point2 outerPoint(bounds.l-(bounds.r-bounds.l)-1, bounds.b-(bounds.t-bounds.b)-1);
|
||||
if (msdfgen::SimpleTrueShapeDistanceFinder::oneShotDistance(shape, outerPoint) > 0) {
|
||||
for (msdfgen::Contour &contour : shape.contours)
|
||||
contour.reverse();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GlyphGeometry::load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry) {
|
||||
msdfgen::GlyphIndex index;
|
||||
if (msdfgen::getGlyphIndex(index, font, codepoint)) {
|
||||
if (load(font, geometryScale, index, preprocessGeometry)) {
|
||||
this->codepoint = codepoint;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GlyphGeometry::edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned long long), double angleThreshold, unsigned long long seed) {
|
||||
fn(shape, angleThreshold, seed);
|
||||
}
|
||||
|
||||
void GlyphGeometry::wrapBox(double scale, double range, double miterLimit) {
|
||||
scale *= geometryScale;
|
||||
range /= geometryScale;
|
||||
box.range = range;
|
||||
box.scale = scale;
|
||||
if (bounds.l < bounds.r && bounds.b < bounds.t) {
|
||||
double l = bounds.l, b = bounds.b, r = bounds.r, t = bounds.t;
|
||||
l -= .5*range, b -= .5*range;
|
||||
r += .5*range, t += .5*range;
|
||||
if (miterLimit > 0)
|
||||
shape.boundMiters(l, b, r, t, .5*range, miterLimit, 1);
|
||||
double w = scale*(r-l);
|
||||
double h = scale*(t-b);
|
||||
box.rect.w = (int) ceil(w)+1;
|
||||
box.rect.h = (int) ceil(h)+1;
|
||||
box.translate.x = -l+.5*(box.rect.w-w)/scale;
|
||||
box.translate.y = -b+.5*(box.rect.h-h)/scale;
|
||||
} else {
|
||||
box.rect.w = 0, box.rect.h = 0;
|
||||
box.translate = msdfgen::Vector2();
|
||||
}
|
||||
}
|
||||
|
||||
void GlyphGeometry::placeBox(int x, int y) {
|
||||
box.rect.x = x, box.rect.y = y;
|
||||
}
|
||||
|
||||
int GlyphGeometry::getIndex() const {
|
||||
return index;
|
||||
}
|
||||
|
||||
msdfgen::GlyphIndex GlyphGeometry::getGlyphIndex() const {
|
||||
return msdfgen::GlyphIndex(index);
|
||||
}
|
||||
|
||||
unicode_t GlyphGeometry::getCodepoint() const {
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
int GlyphGeometry::getIdentifier(GlyphIdentifierType type) const {
|
||||
switch (type) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
return index;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
return (int) codepoint;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const msdfgen::Shape & GlyphGeometry::getShape() const {
|
||||
return shape;
|
||||
}
|
||||
|
||||
double GlyphGeometry::getAdvance() const {
|
||||
return advance;
|
||||
}
|
||||
|
||||
void GlyphGeometry::getBoxRect(int &x, int &y, int &w, int &h) const {
|
||||
x = box.rect.x, y = box.rect.y;
|
||||
w = box.rect.w, h = box.rect.h;
|
||||
}
|
||||
|
||||
void GlyphGeometry::getBoxSize(int &w, int &h) const {
|
||||
w = box.rect.w, h = box.rect.h;
|
||||
}
|
||||
|
||||
double GlyphGeometry::getBoxRange() const {
|
||||
return box.range;
|
||||
}
|
||||
|
||||
msdfgen::Projection GlyphGeometry::getBoxProjection() const {
|
||||
return msdfgen::Projection(msdfgen::Vector2(box.scale), box.translate);
|
||||
}
|
||||
|
||||
double GlyphGeometry::getBoxScale() const {
|
||||
return box.scale;
|
||||
}
|
||||
|
||||
msdfgen::Vector2 GlyphGeometry::getBoxTranslate() const {
|
||||
return box.translate;
|
||||
}
|
||||
|
||||
void GlyphGeometry::getQuadPlaneBounds(double &l, double &b, double &r, double &t) const {
|
||||
if (box.rect.w > 0 && box.rect.h > 0) {
|
||||
double invBoxScale = 1/box.scale;
|
||||
l = geometryScale*(-box.translate.x+.5*invBoxScale);
|
||||
b = geometryScale*(-box.translate.y+.5*invBoxScale);
|
||||
r = geometryScale*(-box.translate.x+(box.rect.w-.5)*invBoxScale);
|
||||
t = geometryScale*(-box.translate.y+(box.rect.h-.5)*invBoxScale);
|
||||
} else
|
||||
l = 0, b = 0, r = 0, t = 0;
|
||||
}
|
||||
|
||||
void GlyphGeometry::getQuadAtlasBounds(double &l, double &b, double &r, double &t) const {
|
||||
if (box.rect.w > 0 && box.rect.h > 0) {
|
||||
l = box.rect.x+.5;
|
||||
b = box.rect.y+.5;
|
||||
r = box.rect.x+box.rect.w-.5;
|
||||
t = box.rect.y+box.rect.h-.5;
|
||||
} else
|
||||
l = 0, b = 0, r = 0, t = 0;
|
||||
}
|
||||
|
||||
bool GlyphGeometry::isWhitespace() const {
|
||||
return shape.contours.empty();
|
||||
}
|
||||
|
||||
GlyphGeometry::operator GlyphBox() const {
|
||||
GlyphBox box;
|
||||
box.index = index;
|
||||
box.advance = advance;
|
||||
getQuadPlaneBounds(box.bounds.l, box.bounds.b, box.bounds.r, box.bounds.t);
|
||||
box.rect.x = this->box.rect.x, box.rect.y = this->box.rect.y, box.rect.w = this->box.rect.w, box.rect.h = this->box.rect.h;
|
||||
return box;
|
||||
}
|
||||
|
||||
}
|
||||
76
Nuake/src/Vendors/msdf-atlas-gen/GlyphGeometry.h
Normal file
76
Nuake/src/Vendors/msdf-atlas-gen/GlyphGeometry.h
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include <msdfgen-ext.h>
|
||||
#include "types.h"
|
||||
#include "GlyphBox.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Represents the shape geometry of a single glyph as well as its configuration
|
||||
class GlyphGeometry {
|
||||
|
||||
public:
|
||||
GlyphGeometry();
|
||||
/// Loads glyph geometry from font
|
||||
bool load(msdfgen::FontHandle *font, double geometryScale, msdfgen::GlyphIndex index, bool preprocessGeometry = true);
|
||||
bool load(msdfgen::FontHandle *font, double geometryScale, unicode_t codepoint, bool preprocessGeometry = true);
|
||||
/// Applies edge coloring to glyph shape
|
||||
void edgeColoring(void (*fn)(msdfgen::Shape &, double, unsigned long long), double angleThreshold, unsigned long long seed);
|
||||
/// Computes the dimensions of the glyph's box as well as the transformation for the generator function
|
||||
void wrapBox(double scale, double range, double miterLimit);
|
||||
/// Sets the glyph's box's position in the atlas
|
||||
void placeBox(int x, int y);
|
||||
/// Returns the glyph's index within the font
|
||||
int getIndex() const;
|
||||
/// Returns the glyph's index as a msdfgen::GlyphIndex
|
||||
msdfgen::GlyphIndex getGlyphIndex() const;
|
||||
/// Returns the Unicode codepoint represented by the glyph or 0 if unknown
|
||||
unicode_t getCodepoint() const;
|
||||
/// Returns the glyph's identifier specified by the supplied identifier type
|
||||
int getIdentifier(GlyphIdentifierType type) const;
|
||||
/// Returns the glyph's shape
|
||||
const msdfgen::Shape & getShape() const;
|
||||
/// Returns the glyph's advance
|
||||
double getAdvance() const;
|
||||
/// Outputs the position and dimensions of the glyph's box in the atlas
|
||||
void getBoxRect(int &x, int &y, int &w, int &h) const;
|
||||
/// Outputs the dimensions of the glyph's box in the atlas
|
||||
void getBoxSize(int &w, int &h) const;
|
||||
/// Returns the range needed to generate the glyph's SDF
|
||||
double getBoxRange() const;
|
||||
/// Returns the projection needed to generate the glyph's bitmap
|
||||
msdfgen::Projection getBoxProjection() const;
|
||||
/// Returns the scale needed to generate the glyph's bitmap
|
||||
double getBoxScale() const;
|
||||
/// Returns the translation vector needed to generate the glyph's bitmap
|
||||
msdfgen::Vector2 getBoxTranslate() const;
|
||||
/// Outputs the bounding box of the glyph as it should be placed on the baseline
|
||||
void getQuadPlaneBounds(double &l, double &b, double &r, double &t) const;
|
||||
/// Outputs the bounding box of the glyph in the atlas
|
||||
void getQuadAtlasBounds(double &l, double &b, double &r, double &t) const;
|
||||
/// Returns true if the glyph is a whitespace and has no geometry
|
||||
bool isWhitespace() const;
|
||||
/// Simplifies to GlyphBox
|
||||
operator GlyphBox() const;
|
||||
|
||||
private:
|
||||
int index;
|
||||
unicode_t codepoint;
|
||||
double geometryScale;
|
||||
msdfgen::Shape shape;
|
||||
msdfgen::Shape::Bounds bounds;
|
||||
double advance;
|
||||
struct {
|
||||
struct {
|
||||
int x, y, w, h;
|
||||
} rect;
|
||||
double range;
|
||||
double scale;
|
||||
msdfgen::Vector2 translate;
|
||||
} box;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
45
Nuake/src/Vendors/msdf-atlas-gen/ImmediateAtlasGenerator.h
Normal file
45
Nuake/src/Vendors/msdf-atlas-gen/ImmediateAtlasGenerator.h
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "GlyphBox.h"
|
||||
#include "Workload.h"
|
||||
#include "AtlasGenerator.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/**
|
||||
* An implementation of AtlasGenerator that uses the specified generator function
|
||||
* and AtlasStorage class and generates glyph bitmaps immediately
|
||||
* (does not return until all submitted work is finished),
|
||||
* but may use multiple threads (setThreadCount).
|
||||
*/
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
class ImmediateAtlasGenerator {
|
||||
|
||||
public:
|
||||
ImmediateAtlasGenerator();
|
||||
ImmediateAtlasGenerator(int width, int height);
|
||||
void generate(const GlyphGeometry *glyphs, int count);
|
||||
void rearrange(int width, int height, const Remap *remapping, int count);
|
||||
void resize(int width, int height);
|
||||
/// Sets attributes for the generator function
|
||||
void setAttributes(const GeneratorAttributes &attributes);
|
||||
/// Sets the number of threads to be run by generate
|
||||
void setThreadCount(int threadCount);
|
||||
/// Allows access to the underlying AtlasStorage
|
||||
const AtlasStorage & atlasStorage() const;
|
||||
|
||||
private:
|
||||
AtlasStorage storage;
|
||||
std::vector<GlyphBox> layout;
|
||||
std::vector<T> glyphBuffer;
|
||||
std::vector<byte> errorCorrectionBuffer;
|
||||
GeneratorAttributes attributes;
|
||||
int threadCount;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#include "ImmediateAtlasGenerator.hpp"
|
||||
77
Nuake/src/Vendors/msdf-atlas-gen/ImmediateAtlasGenerator.hpp
Normal file
77
Nuake/src/Vendors/msdf-atlas-gen/ImmediateAtlasGenerator.hpp
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
#include "ImmediateAtlasGenerator.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::ImmediateAtlasGenerator() : threadCount(1) { }
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::ImmediateAtlasGenerator(int width, int height) : storage(width, height), threadCount(1) { }
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
void ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::generate(const GlyphGeometry *glyphs, int count) {
|
||||
int maxBoxArea = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GlyphBox box = glyphs[i];
|
||||
maxBoxArea = std::max(maxBoxArea, box.rect.w*box.rect.h);
|
||||
layout.push_back((GlyphBox &&) box);
|
||||
}
|
||||
int threadBufferSize = N*maxBoxArea;
|
||||
if (threadCount*threadBufferSize > (int) glyphBuffer.size())
|
||||
glyphBuffer.resize(threadCount*threadBufferSize);
|
||||
if (threadCount*maxBoxArea > (int) errorCorrectionBuffer.size())
|
||||
errorCorrectionBuffer.resize(threadCount*maxBoxArea);
|
||||
std::vector<GeneratorAttributes> threadAttributes(threadCount);
|
||||
for (int i = 0; i < threadCount; ++i) {
|
||||
threadAttributes[i] = attributes;
|
||||
threadAttributes[i].config.errorCorrection.buffer = errorCorrectionBuffer.data()+i*maxBoxArea;
|
||||
}
|
||||
|
||||
Workload([this, glyphs, &threadAttributes, threadBufferSize](int i, int threadNo) -> bool {
|
||||
const GlyphGeometry &glyph = glyphs[i];
|
||||
if (!glyph.isWhitespace()) {
|
||||
int l, b, w, h;
|
||||
glyph.getBoxRect(l, b, w, h);
|
||||
msdfgen::BitmapRef<T, N> glyphBitmap(glyphBuffer.data()+threadNo*threadBufferSize, w, h);
|
||||
GEN_FN(glyphBitmap, glyph, threadAttributes[threadNo]);
|
||||
storage.put(l, b, msdfgen::BitmapConstRef<T, N>(glyphBitmap));
|
||||
}
|
||||
return true;
|
||||
}, count).finish(threadCount);
|
||||
}
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
void ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::rearrange(int width, int height, const Remap *remapping, int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
layout[remapping[i].index].rect.x = remapping[i].target.x;
|
||||
layout[remapping[i].index].rect.y = remapping[i].target.y;
|
||||
}
|
||||
AtlasStorage newStorage((AtlasStorage &&) storage, width, height, remapping, count);
|
||||
storage = (AtlasStorage &&) newStorage;
|
||||
}
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
void ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::resize(int width, int height) {
|
||||
AtlasStorage newStorage((AtlasStorage &&) storage, width, height);
|
||||
storage = (AtlasStorage &&) newStorage;
|
||||
}
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
void ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::setAttributes(const GeneratorAttributes &attributes) {
|
||||
this->attributes = attributes;
|
||||
}
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
void ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::setThreadCount(int threadCount) {
|
||||
this->threadCount = threadCount;
|
||||
}
|
||||
|
||||
template <typename T, int N, GeneratorFunction<T, N> GEN_FN, class AtlasStorage>
|
||||
const AtlasStorage & ImmediateAtlasGenerator<T, N, GEN_FN, AtlasStorage>::atlasStorage() const {
|
||||
return storage;
|
||||
}
|
||||
|
||||
}
|
||||
21
Nuake/src/Vendors/msdf-atlas-gen/LICENSE.txt
Normal file
21
Nuake/src/Vendors/msdf-atlas-gen/LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Viktor Chlumsky
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
142
Nuake/src/Vendors/msdf-atlas-gen/README.md
Normal file
142
Nuake/src/Vendors/msdf-atlas-gen/README.md
Normal file
@@ -0,0 +1,142 @@
|
||||
|
||||
# Multi-channel signed distance field atlas generator
|
||||
|
||||
This is a utility for generating compact font atlases using [MSDFgen](https://github.com/Chlumsky/msdfgen).
|
||||
|
||||
The atlas generator loads a subset of glyphs from a TTF or OTF font file, generates a distance field for each of them, and tightly packs them into an atlas bitmap (example below). The finished atlas and/or its layout metadata can be exported as an [Artery Font](https://github.com/Chlumsky/artery-font-format) file, a plain image file, a CSV sheet or a structured JSON file.
|
||||
|
||||

|
||||
|
||||
A font atlas is typically stored in texture memory and used to draw text in real-time rendering contexts such as video games.
|
||||
|
||||
- See what's new in the [changelog](CHANGELOG.md).
|
||||
|
||||
## Atlas types
|
||||
|
||||
The atlas generator can generate the following six types of atlases.
|
||||
|
||||
| |Hard mask|Soft mask|SDF|PSDF|MSDF|MTSDF|
|
||||
|-|-|-|-|-|-|-|
|
||||
| |||||||
|
||||
|Channels:|1 (1-bit)|1|1|1|3|4|
|
||||
|Anti-aliasing:|-|Yes|Yes|Yes|Yes|Yes|
|
||||
|Scalability:|-|-|Yes|Yes|Yes|Yes|
|
||||
|Sharp corners:|-|-|-|-|Yes|Yes|
|
||||
|Soft effects:|-|-|Yes|-|-|Yes|
|
||||
|Hard effects:|-|-|-|Yes|Yes|Yes|
|
||||
|
||||
Notes:
|
||||
- *Sharp corners* refers to preservation of corner sharpness when upscaled.
|
||||
- *Soft effects* refers to the support of effects that use true distance, such as glows, rounded borders, or simplified shadows.
|
||||
- *Hard effects* refers to the support of effects that use pseudo-distance, such as mitered borders or thickness adjustment.
|
||||
|
||||
## Getting started
|
||||
|
||||
This project can be used either as a library or as a standalone console program.
|
||||
To start using the program immediately, there is a Windows binary available for download in the ["Releases" section](https://github.com/Chlumsky/msdf-atlas-gen/releases).
|
||||
To build the project, you may use the included [Visual Studio solution](msdf-atlas-gen.sln) or the [Unix Makefile](Makefile).
|
||||
|
||||
## Command line arguments
|
||||
|
||||
Use the following command line arguments for the standalone version of the atlas generator.
|
||||
|
||||
### Input
|
||||
|
||||
- `-font <fontfile.ttf/otf>` (required) – sets the input font file.
|
||||
- `-charset <charset.txt>` – sets the character set. The ASCII charset will be used if not specified. See [the syntax specification](#character-set-specification-syntax) of `charset.txt`.
|
||||
- `-glyphset <glyphset.txt>` – sets the set of input glyphs using their indices within the font file. See [the syntax specification](#glyph-set-specification).
|
||||
- `-fontscale <scale>` – applies a scaling transformation to the font's glyphs. Mainly to be used to generate multiple sizes in a single atlas, otherwise use [`-size`](#glyph-configuration).
|
||||
- `-fontname <name>` – sets a name for the font that will be stored in certain output files as metadata.
|
||||
- `-and` – separates multiple inputs to be combined into a single atlas.
|
||||
|
||||
### Bitmap atlas type
|
||||
|
||||
`-type <type>` – see [Atlas types](#atlas-types)
|
||||
|
||||
`<type>` can be one of:
|
||||
|
||||
- `hardmask` – a non-anti-aliased binary image
|
||||
- `softmask` – an anti-aliased image
|
||||
- `sdf` – a true signed distance field (SDF)
|
||||
- `psdf` – a pseudo-distance field
|
||||
- `msdf` (default) – a multi-channel signed distance field (MSDF)
|
||||
- `mtsdf` – a combination of MSDF and true SDF in the alpha channel
|
||||
|
||||
### Atlas image format
|
||||
|
||||
`-format <format>`
|
||||
|
||||
`<format>` can be one of:
|
||||
|
||||
- `png` – a compressed PNG image
|
||||
- `bmp` – an uncompressed BMP image
|
||||
- `tiff` – an uncompressed floating-point TIFF image
|
||||
- `text` – a sequence of pixel values in plain text
|
||||
- `textfloat` – a sequence of floating-point pixel values in plain text
|
||||
- `bin` – a sequence of pixel values encoded as raw bytes of data
|
||||
- `binfloat` – a sequence of pixel values encoded as raw 32-bit floating-point values
|
||||
|
||||
### Atlas dimensions
|
||||
|
||||
`-dimensions <width> <height>` – sets fixed atlas dimensions
|
||||
|
||||
Alternativelly, the minimum possible dimensions may be selected automatically if a dimensions constraint is set instead:
|
||||
|
||||
- `-pots` – a power-of-two square
|
||||
- `-potr` – a power-of-two square or rectangle (2:1)
|
||||
- `-square` – any square dimensions
|
||||
- `-square2` – square with even side length
|
||||
- `-square4` (default) – square with side length divisible by four
|
||||
|
||||
### Outputs
|
||||
|
||||
Any non-empty subset of the following may be specified:
|
||||
|
||||
- `-imageout <filename.*>` – saves the atlas bitmap as a plain image file. Format matches `-format`
|
||||
- `-json <filename.json>` – writes the atlas's layout data as well as other metrics into a structured JSON file
|
||||
- `-csv <filename.csv>` – writes the glyph layout data into a simple CSV file
|
||||
- `-arfont <filename.arfont>` – saves the atlas and its layout data as an [Artery Font](https://github.com/Chlumsky/artery-font-format) file
|
||||
- `-shadronpreview <filename.shadron> <sample text>` – generates a [Shadron script](https://www.arteryengine.com/shadron/) that uses the generated atlas to draw a sample text as a preview
|
||||
|
||||
### Glyph configuration
|
||||
|
||||
- `-size <EM size>` – sets the size of the glyphs in the atlas in pixels per EM
|
||||
- `-minsize <EM size>` – sets the minimum size. The largest possible size that fits the same atlas dimensions will be used
|
||||
- `-emrange <EM range>` – sets the distance field range in EM's
|
||||
- `-pxrange <pixel range>` (default = 2) – sets the distance field range in output pixels
|
||||
|
||||
### Distance field generator settings
|
||||
|
||||
- `-angle <angle>` – sets the minimum angle between adjacent edges to be considered a corner. Append D for degrees (`msdf` / `mtsdf` only)
|
||||
- `-coloringstrategy <simple / inktrap / distance>` – selects the edge coloring heuristic (`msdf` / `mtsdf` only)
|
||||
- `-errorcorrection <mode>` – selects the error correction algorithm. Use `help` as mode for more information (`msdf` / `mtsdf` only)
|
||||
- `-miterlimit <value>` – sets the miter limit that limits the extension of each glyph's bounding box due to very sharp corners (`psdf` / `msdf` / `mtsdf` only)
|
||||
- `-overlap` – switches to distance field generator with support for overlapping contours
|
||||
- `-nopreprocess` – disables path preprocessing which resolves self-intersections and overlapping contours
|
||||
- `-scanline` – performs an additional scanline pass to fix the signs of the distances
|
||||
- `-seed <N>` – sets the initial seed for the edge coloring heuristic
|
||||
- `-threads <N>` – sets the number of threads for the parallel computation (0 = auto)
|
||||
|
||||
Use `-help` for an exhaustive list of options.
|
||||
|
||||
## Character set specification syntax
|
||||
|
||||
The character set file is a text file with UTF-8 or ASCII encoding.
|
||||
The characters can be denoted in the following ways:
|
||||
|
||||
- Single character: `'A'` (UTF-8 encoded), `65` (decimal Unicode), `0x41` (hexadecimal Unicode)
|
||||
- Range of characters: `['A', 'Z']`, `[65, 90]`, `[0x41, 0x5a]`
|
||||
- String of characters: `"ABCDEFGHIJKLMNOPQRSTUVWXYZ"` (UTF-8 encoded)
|
||||
|
||||
The entries should be separated by commas or whitespace.
|
||||
In between quotation marks, backslash is used as the escape character (e.g. `'\''`, `'\\'`, `"!\"#"`).
|
||||
The order in which characters appear is not taken into consideration.
|
||||
|
||||
Additionally, the include directive can be used to include other charset files and combine character sets in a hierarchical way.
|
||||
It must be written on a separate line:
|
||||
|
||||
`@include "base-charset.txt"`
|
||||
|
||||
### Glyph set specification
|
||||
|
||||
The syntax of the glyph set specification is mostly the same as that of a character set, but only numeric values (decimal and hexadecimal) are allowed.
|
||||
14
Nuake/src/Vendors/msdf-atlas-gen/Rectangle.h
Normal file
14
Nuake/src/Vendors/msdf-atlas-gen/Rectangle.h
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
struct Rectangle {
|
||||
int x, y, w, h;
|
||||
};
|
||||
|
||||
struct OrientedRectangle : Rectangle {
|
||||
bool rotated;
|
||||
};
|
||||
|
||||
}
|
||||
143
Nuake/src/Vendors/msdf-atlas-gen/RectanglePacker.cpp
Normal file
143
Nuake/src/Vendors/msdf-atlas-gen/RectanglePacker.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
#include "RectanglePacker.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
#define WORST_FIT 0x7fffffff
|
||||
|
||||
template <typename T>
|
||||
static void removeFromUnorderedVector(std::vector<T> &vector, size_t index) {
|
||||
if (index != vector.size()-1)
|
||||
std::swap(vector[index], vector.back());
|
||||
vector.pop_back();
|
||||
}
|
||||
|
||||
int RectanglePacker::rateFit(int w, int h, int sw, int sh) {
|
||||
return std::min(sw-w, sh-h);
|
||||
}
|
||||
|
||||
RectanglePacker::RectanglePacker() : RectanglePacker(0, 0) { }
|
||||
|
||||
RectanglePacker::RectanglePacker(int width, int height) {
|
||||
if (width > 0 && height > 0)
|
||||
spaces.push_back(Rectangle { 0, 0, width, height });
|
||||
}
|
||||
|
||||
void RectanglePacker::splitSpace(int index, int w, int h) {
|
||||
Rectangle space = spaces[index];
|
||||
removeFromUnorderedVector(spaces, index);
|
||||
Rectangle a = { space.x, space.y+h, w, space.h-h };
|
||||
Rectangle b = { space.x+w, space.y, space.w-w, h };
|
||||
if (w*(space.h-h) <= h*(space.w-w))
|
||||
a.w = space.w;
|
||||
else
|
||||
b.h = space.h;
|
||||
if (a.w > 0 && a.h > 0)
|
||||
spaces.push_back(a);
|
||||
if (b.w > 0 && b.h > 0)
|
||||
spaces.push_back(b);
|
||||
}
|
||||
|
||||
int RectanglePacker::pack(Rectangle *rectangles, int count) {
|
||||
std::vector<int> remainingRects(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
remainingRects[i] = i;
|
||||
while (!remainingRects.empty()) {
|
||||
int bestFit = WORST_FIT;
|
||||
int bestSpace = -1;
|
||||
int bestRect = -1;
|
||||
for (size_t i = 0; i < spaces.size(); ++i) {
|
||||
const Rectangle &space = spaces[i];
|
||||
for (size_t j = 0; j < remainingRects.size(); ++j) {
|
||||
const Rectangle &rect = rectangles[remainingRects[j]];
|
||||
if (rect.w == space.w && rect.h == space.h) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
goto BEST_FIT_FOUND;
|
||||
}
|
||||
if (rect.w <= space.w && rect.h <= space.h) {
|
||||
int fit = rateFit(rect.w, rect.h, space.w, space.h);
|
||||
if (fit < bestFit) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
bestFit = fit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestSpace < 0 || bestRect < 0)
|
||||
break;
|
||||
BEST_FIT_FOUND:
|
||||
Rectangle &rect = rectangles[remainingRects[bestRect]];
|
||||
rect.x = spaces[bestSpace].x;
|
||||
rect.y = spaces[bestSpace].y;
|
||||
splitSpace(bestSpace, rect.w, rect.h);
|
||||
removeFromUnorderedVector(remainingRects, bestRect);
|
||||
}
|
||||
return (int) remainingRects.size();
|
||||
}
|
||||
|
||||
int RectanglePacker::pack(OrientedRectangle *rectangles, int count) {
|
||||
std::vector<int> remainingRects(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
remainingRects[i] = i;
|
||||
while (!remainingRects.empty()) {
|
||||
int bestFit = WORST_FIT;
|
||||
int bestSpace = -1;
|
||||
int bestRect = -1;
|
||||
bool bestRotated = false;
|
||||
for (size_t i = 0; i < spaces.size(); ++i) {
|
||||
const Rectangle &space = spaces[i];
|
||||
for (size_t j = 0; j < remainingRects.size(); ++j) {
|
||||
const OrientedRectangle &rect = rectangles[remainingRects[j]];
|
||||
if (rect.w == space.w && rect.h == space.h) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
bestRotated = false;
|
||||
goto BEST_FIT_FOUND;
|
||||
}
|
||||
if (rect.h == space.w && rect.w == space.h) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
bestRotated = true;
|
||||
goto BEST_FIT_FOUND;
|
||||
}
|
||||
if (rect.w <= space.w && rect.h <= space.h) {
|
||||
int fit = rateFit(rect.w, rect.h, space.w, space.h);
|
||||
if (fit < bestFit) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
bestRotated = false;
|
||||
bestFit = fit;
|
||||
}
|
||||
}
|
||||
if (rect.h <= space.w && rect.w <= space.h) {
|
||||
int fit = rateFit(rect.h, rect.w, space.w, space.h);
|
||||
if (fit < bestFit) {
|
||||
bestSpace = i;
|
||||
bestRect = j;
|
||||
bestRotated = true;
|
||||
bestFit = fit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestSpace < 0 || bestRect < 0)
|
||||
break;
|
||||
BEST_FIT_FOUND:
|
||||
OrientedRectangle &rect = rectangles[remainingRects[bestRect]];
|
||||
rect.x = spaces[bestSpace].x;
|
||||
rect.y = spaces[bestSpace].y;
|
||||
rect.rotated = bestRotated;
|
||||
if (bestRotated)
|
||||
splitSpace(bestSpace, rect.h, rect.w);
|
||||
else
|
||||
splitSpace(bestSpace, rect.w, rect.h);
|
||||
removeFromUnorderedVector(remainingRects, bestRect);
|
||||
}
|
||||
return (int) remainingRects.size();
|
||||
}
|
||||
|
||||
}
|
||||
28
Nuake/src/Vendors/msdf-atlas-gen/RectanglePacker.h
Normal file
28
Nuake/src/Vendors/msdf-atlas-gen/RectanglePacker.h
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "Rectangle.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Guillotine 2D single bin packer
|
||||
class RectanglePacker {
|
||||
|
||||
public:
|
||||
RectanglePacker();
|
||||
RectanglePacker(int width, int height);
|
||||
/// Packs the rectangle array, returns how many didn't fit (0 on success)
|
||||
int pack(Rectangle *rectangles, int count);
|
||||
int pack(OrientedRectangle *rectangles, int count);
|
||||
|
||||
private:
|
||||
std::vector<Rectangle> spaces;
|
||||
|
||||
static int rateFit(int w, int h, int sw, int sh);
|
||||
|
||||
void splitSpace(int index, int w, int h);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
15
Nuake/src/Vendors/msdf-atlas-gen/Remap.h
Normal file
15
Nuake/src/Vendors/msdf-atlas-gen/Remap.h
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Represents the repositioning of a subsection of the atlas
|
||||
struct Remap {
|
||||
int index;
|
||||
struct {
|
||||
int x, y;
|
||||
} source, target;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
}
|
||||
168
Nuake/src/Vendors/msdf-atlas-gen/TightAtlasPacker.cpp
Normal file
168
Nuake/src/Vendors/msdf-atlas-gen/TightAtlasPacker.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
|
||||
#include "TightAtlasPacker.h"
|
||||
|
||||
#include <vector>
|
||||
#include "Rectangle.h"
|
||||
#include "rectangle-packing.h"
|
||||
#include "size-selectors.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
int TightAtlasPacker::tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, int padding, double scale, double range, double miterLimit) {
|
||||
// Wrap glyphs into boxes
|
||||
std::vector<Rectangle> rectangles;
|
||||
std::vector<GlyphGeometry *> rectangleGlyphs;
|
||||
rectangles.reserve(count);
|
||||
rectangleGlyphs.reserve(count);
|
||||
for (GlyphGeometry *glyph = glyphs, *end = glyphs+count; glyph < end; ++glyph) {
|
||||
if (!glyph->isWhitespace()) {
|
||||
Rectangle rect = { };
|
||||
glyph->wrapBox(scale, range, miterLimit);
|
||||
glyph->getBoxSize(rect.w, rect.h);
|
||||
if (rect.w > 0 && rect.h > 0) {
|
||||
rectangles.push_back(rect);
|
||||
rectangleGlyphs.push_back(glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
// No non-zero size boxes?
|
||||
if (rectangles.empty()) {
|
||||
if (width < 0 || height < 0)
|
||||
width = 0, height = 0;
|
||||
return 0;
|
||||
}
|
||||
// Box rectangle packing
|
||||
if (width < 0 || height < 0) {
|
||||
std::pair<int, int> dimensions = std::make_pair(width, height);
|
||||
switch (dimensionsConstraint) {
|
||||
case DimensionsConstraint::POWER_OF_TWO_SQUARE:
|
||||
dimensions = packRectangles<SquarePowerOfTwoSizeSelector>(rectangles.data(), rectangles.size(), padding);
|
||||
break;
|
||||
case DimensionsConstraint::POWER_OF_TWO_RECTANGLE:
|
||||
dimensions = packRectangles<PowerOfTwoSizeSelector>(rectangles.data(), rectangles.size(), padding);
|
||||
break;
|
||||
case DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE:
|
||||
dimensions = packRectangles<SquareSizeSelector<4> >(rectangles.data(), rectangles.size(), padding);
|
||||
break;
|
||||
case DimensionsConstraint::EVEN_SQUARE:
|
||||
dimensions = packRectangles<SquareSizeSelector<2> >(rectangles.data(), rectangles.size(), padding);
|
||||
break;
|
||||
case DimensionsConstraint::SQUARE:
|
||||
dimensions = packRectangles<SquareSizeSelector<> >(rectangles.data(), rectangles.size(), padding);
|
||||
break;
|
||||
}
|
||||
if (!(dimensions.first > 0 && dimensions.second > 0))
|
||||
return -1;
|
||||
width = dimensions.first, height = dimensions.second;
|
||||
} else {
|
||||
if (int result = packRectangles(rectangles.data(), rectangles.size(), width, height, padding))
|
||||
return result;
|
||||
}
|
||||
// Set glyph box placement
|
||||
for (size_t i = 0; i < rectangles.size(); ++i)
|
||||
rectangleGlyphs[i]->placeBox(rectangles[i].x, height-(rectangles[i].y+rectangles[i].h));
|
||||
return 0;
|
||||
}
|
||||
|
||||
double TightAtlasPacker::packAndScale(GlyphGeometry *glyphs, int count, int width, int height, int padding, double unitRange, double pxRange, double miterLimit, double tolerance) {
|
||||
bool lastResult = false;
|
||||
#define TRY_PACK(scale) (lastResult = !tryPack(glyphs, count, DimensionsConstraint(), width, height, padding, (scale), unitRange+pxRange/(scale), miterLimit))
|
||||
double minScale = 1, maxScale = 1;
|
||||
if (TRY_PACK(1)) {
|
||||
while (maxScale < 1e+32 && ((maxScale = 2*minScale), TRY_PACK(maxScale)))
|
||||
minScale = maxScale;
|
||||
} else {
|
||||
while (minScale > 1e-32 && ((minScale = .5*maxScale), !TRY_PACK(minScale)))
|
||||
maxScale = minScale;
|
||||
}
|
||||
if (minScale == maxScale)
|
||||
return 0;
|
||||
while (minScale/maxScale < 1-tolerance) {
|
||||
double midScale = .5*(minScale+maxScale);
|
||||
if (TRY_PACK(midScale))
|
||||
minScale = midScale;
|
||||
else
|
||||
maxScale = midScale;
|
||||
}
|
||||
if (!lastResult)
|
||||
TRY_PACK(minScale);
|
||||
return minScale;
|
||||
}
|
||||
|
||||
TightAtlasPacker::TightAtlasPacker() :
|
||||
width(-1), height(-1),
|
||||
padding(0),
|
||||
dimensionsConstraint(DimensionsConstraint::POWER_OF_TWO_SQUARE),
|
||||
scale(-1),
|
||||
minScale(1),
|
||||
unitRange(0),
|
||||
pxRange(0),
|
||||
miterLimit(0),
|
||||
scaleMaximizationTolerance(.001)
|
||||
{ }
|
||||
|
||||
int TightAtlasPacker::pack(GlyphGeometry *glyphs, int count) {
|
||||
double initialScale = scale > 0 ? scale : minScale;
|
||||
if (initialScale > 0) {
|
||||
if (int remaining = tryPack(glyphs, count, dimensionsConstraint, width, height, padding, initialScale, unitRange+pxRange/initialScale, miterLimit))
|
||||
return remaining;
|
||||
} else if (width < 0 || height < 0)
|
||||
return -1;
|
||||
if (scale <= 0)
|
||||
scale = packAndScale(glyphs, count, width, height, padding, unitRange, pxRange, miterLimit, scaleMaximizationTolerance);
|
||||
if (scale <= 0)
|
||||
return -1;
|
||||
pxRange += scale*unitRange;
|
||||
unitRange = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setDimensions(int width, int height) {
|
||||
this->width = width, this->height = height;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::unsetDimensions() {
|
||||
width = -1, height = -1;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setDimensionsConstraint(DimensionsConstraint dimensionsConstraint) {
|
||||
this->dimensionsConstraint = dimensionsConstraint;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setPadding(int padding) {
|
||||
this->padding = padding;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setScale(double scale) {
|
||||
this->scale = scale;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setMinimumScale(double minScale) {
|
||||
this->minScale = minScale;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setUnitRange(double unitRange) {
|
||||
this->unitRange = unitRange;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setPixelRange(double pxRange) {
|
||||
this->pxRange = pxRange;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::setMiterLimit(double miterLimit) {
|
||||
this->miterLimit = miterLimit;
|
||||
}
|
||||
|
||||
void TightAtlasPacker::getDimensions(int &width, int &height) const {
|
||||
width = this->width, height = this->height;
|
||||
}
|
||||
|
||||
double TightAtlasPacker::getScale() const {
|
||||
return scale;
|
||||
}
|
||||
|
||||
double TightAtlasPacker::getPixelRange() const {
|
||||
return pxRange;
|
||||
}
|
||||
|
||||
}
|
||||
71
Nuake/src/Vendors/msdf-atlas-gen/TightAtlasPacker.h
Normal file
71
Nuake/src/Vendors/msdf-atlas-gen/TightAtlasPacker.h
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GlyphGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/**
|
||||
* This class computes the layout of a static atlas and may optionally
|
||||
* also find the minimum required dimensions and/or the maximum glyph scale
|
||||
*/
|
||||
class TightAtlasPacker {
|
||||
|
||||
public:
|
||||
/// Constraints for the atlas's dimensions - see size selectors for more info
|
||||
enum class DimensionsConstraint {
|
||||
POWER_OF_TWO_SQUARE,
|
||||
POWER_OF_TWO_RECTANGLE,
|
||||
MULTIPLE_OF_FOUR_SQUARE,
|
||||
EVEN_SQUARE,
|
||||
SQUARE
|
||||
};
|
||||
|
||||
TightAtlasPacker();
|
||||
|
||||
/// Computes the layout for the array of glyphs. Returns 0 on success
|
||||
int pack(GlyphGeometry *glyphs, int count);
|
||||
|
||||
/// Sets the atlas's dimensions to be fixed
|
||||
void setDimensions(int width, int height);
|
||||
/// Sets the atlas's dimensions to be determined during pack
|
||||
void unsetDimensions();
|
||||
/// Sets the constraint to be used when determining dimensions
|
||||
void setDimensionsConstraint(DimensionsConstraint dimensionsConstraint);
|
||||
/// Sets the padding between glyph boxes
|
||||
void setPadding(int padding);
|
||||
/// Sets fixed glyph scale
|
||||
void setScale(double scale);
|
||||
/// Sets the minimum glyph scale
|
||||
void setMinimumScale(double minScale);
|
||||
/// Sets the unit component of the total distance range
|
||||
void setUnitRange(double unitRange);
|
||||
/// Sets the pixel component of the total distance range
|
||||
void setPixelRange(double pxRange);
|
||||
/// Sets the miter limit for bounds computation
|
||||
void setMiterLimit(double miterLimit);
|
||||
|
||||
/// Outputs the atlas's final dimensions
|
||||
void getDimensions(int &width, int &height) const;
|
||||
/// Returns the final glyph scale
|
||||
double getScale() const;
|
||||
/// Returns the final combined pixel range (including converted unit range)
|
||||
double getPixelRange() const;
|
||||
|
||||
private:
|
||||
int width, height;
|
||||
int padding;
|
||||
DimensionsConstraint dimensionsConstraint;
|
||||
double scale;
|
||||
double minScale;
|
||||
double unitRange;
|
||||
double pxRange;
|
||||
double miterLimit;
|
||||
double scaleMaximizationTolerance;
|
||||
|
||||
static int tryPack(GlyphGeometry *glyphs, int count, DimensionsConstraint dimensionsConstraint, int &width, int &height, int padding, double scale, double range, double miterLimit);
|
||||
static double packAndScale(GlyphGeometry *glyphs, int count, int width, int height, int padding, double unitRange, double pxRange, double miterLimit, double tolerance);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
50
Nuake/src/Vendors/msdf-atlas-gen/Workload.cpp
Normal file
50
Nuake/src/Vendors/msdf-atlas-gen/Workload.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
|
||||
#include "Workload.h"
|
||||
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <algorithm>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
Workload::Workload() : chunks(0) { }
|
||||
|
||||
Workload::Workload(const std::function<bool(int, int)> &workerFunction, int chunks) : workerFunction(workerFunction), chunks(chunks) { }
|
||||
|
||||
bool Workload::finishSequential() {
|
||||
for (int i = 0; i < chunks; ++i)
|
||||
if (!workerFunction(i, 0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Workload::finishParallel(int threadCount) {
|
||||
bool result = true;
|
||||
std::atomic<int> next(0);
|
||||
std::function<void(int)> threadWorker = [this, &result, &next](int threadNo) {
|
||||
for (int i = next++; result && i < chunks; i = next++) {
|
||||
if (!workerFunction(i, threadNo))
|
||||
result = false;
|
||||
}
|
||||
};
|
||||
std::vector<std::thread> threads;
|
||||
threads.reserve(threadCount);
|
||||
for (int i = 0; i < threadCount; ++i)
|
||||
threads.emplace_back(threadWorker, i);
|
||||
for (std::thread &thread : threads)
|
||||
thread.join();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Workload::finish(int threadCount) {
|
||||
if (!chunks)
|
||||
return true;
|
||||
if (threadCount == 1 || chunks == 1)
|
||||
return finishSequential();
|
||||
if (threadCount > 1)
|
||||
return finishParallel(std::min(threadCount, chunks));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
32
Nuake/src/Vendors/msdf-atlas-gen/Workload.h
Normal file
32
Nuake/src/Vendors/msdf-atlas-gen/Workload.h
Normal file
@@ -0,0 +1,32 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/**
|
||||
* This function allows to split a workload into multiple threads.
|
||||
* The worker function:
|
||||
* bool FN(int chunk, int threadNo);
|
||||
* should process the given chunk (out of chunks) and return true.
|
||||
* If false is returned, the process is interrupted.
|
||||
*/
|
||||
class Workload {
|
||||
|
||||
public:
|
||||
Workload();
|
||||
Workload(const std::function<bool(int, int)> &workerFunction, int chunks);
|
||||
/// Runs the process and returns true if all chunks have been processed
|
||||
bool finish(int threadCount);
|
||||
|
||||
private:
|
||||
std::function<bool(int, int)> workerFunction;
|
||||
int chunks;
|
||||
|
||||
bool finishSequential();
|
||||
bool finishParallel(int threadCount);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
191
Nuake/src/Vendors/msdf-atlas-gen/artery-font-export.cpp
Normal file
191
Nuake/src/Vendors/msdf-atlas-gen/artery-font-export.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
|
||||
#include "artery-font-export.h"
|
||||
|
||||
/*#include <std-artery-font.h>
|
||||
#include <artery-font/stdio-serialization.h>
|
||||
#include "GlyphGeometry.h"
|
||||
#include "image-encode.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
static artery_font::ImageType convertImageType(ImageType imageType) {
|
||||
switch (imageType) {
|
||||
case ImageType::HARD_MASK:
|
||||
case ImageType::SOFT_MASK:
|
||||
return artery_font::IMAGE_LINEAR_MASK;
|
||||
case ImageType::SDF:
|
||||
return artery_font::IMAGE_SDF;
|
||||
case ImageType::PSDF:
|
||||
return artery_font::IMAGE_PSDF;
|
||||
case ImageType::MSDF:
|
||||
return artery_font::IMAGE_MSDF;
|
||||
case ImageType::MTSDF:
|
||||
return artery_font::IMAGE_MTSDF;
|
||||
}
|
||||
return artery_font::IMAGE_NONE;
|
||||
}
|
||||
|
||||
static artery_font::CodepointType convertCodepointType(GlyphIdentifierType glyphIdentifierType) {
|
||||
switch (glyphIdentifierType) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
return artery_font::CP_INDEXED;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
return artery_font::CP_UNICODE;
|
||||
}
|
||||
return artery_font::CP_UNSPECIFIED;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
static bool encodeTiff(std::vector<byte> &output, const msdfgen::BitmapConstRef<T, N> &atlas) {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static artery_font::PixelFormat getPixelFormat();
|
||||
|
||||
template <>
|
||||
artery_font::PixelFormat getPixelFormat<byte>() {
|
||||
return artery_font::PIXEL_UNSIGNED8;
|
||||
}
|
||||
template <>
|
||||
artery_font::PixelFormat getPixelFormat<float>() {
|
||||
return artery_font::PIXEL_FLOAT32;
|
||||
}
|
||||
|
||||
template <typename REAL, typename T, int N>
|
||||
bool exportArteryFont(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<T, N> &atlas, const char *filename, const ArteryFontExportProperties &properties) {
|
||||
artery_font::StdArteryFont<REAL> arfont = { };
|
||||
arfont.metadataFormat = artery_font::METADATA_NONE;
|
||||
|
||||
for (int i = 0; i < fontCount; ++i) {
|
||||
const FontGeometry &font = fonts[i];
|
||||
GlyphIdentifierType identifierType = font.getPreferredIdentifierType();
|
||||
const msdfgen::FontMetrics &fontMetrics = font.getMetrics();
|
||||
artery_font::StdFontVariant<REAL> fontVariant = { };
|
||||
fontVariant.codepointType = convertCodepointType(identifierType);
|
||||
fontVariant.imageType = convertImageType(properties.imageType);
|
||||
fontVariant.metrics.fontSize = REAL(properties.fontSize*fontMetrics.emSize);
|
||||
if (properties.imageType != ImageType::HARD_MASK)
|
||||
fontVariant.metrics.distanceRange = REAL(properties.pxRange);
|
||||
fontVariant.metrics.emSize = REAL(fontMetrics.emSize);
|
||||
fontVariant.metrics.ascender = REAL(fontMetrics.ascenderY);
|
||||
fontVariant.metrics.descender = REAL(fontMetrics.descenderY);
|
||||
fontVariant.metrics.lineHeight = REAL(fontMetrics.lineHeight);
|
||||
fontVariant.metrics.underlineY = REAL(fontMetrics.underlineY);
|
||||
fontVariant.metrics.underlineThickness = REAL(fontMetrics.underlineThickness);
|
||||
const char *name = font.getName();
|
||||
if (name)
|
||||
fontVariant.name.string = name;
|
||||
fontVariant.glyphs = artery_font::StdList<artery_font::Glyph<REAL> >(font.getGlyphs().size());
|
||||
int j = 0;
|
||||
for (const GlyphGeometry &glyphGeom : font.getGlyphs()) {
|
||||
artery_font::Glyph<REAL> &glyph = fontVariant.glyphs[j++];
|
||||
glyph.codepoint = glyphGeom.getIdentifier(identifierType);
|
||||
glyph.image = 0;
|
||||
double l, b, r, t;
|
||||
glyphGeom.getQuadPlaneBounds(l, b, r, t);
|
||||
glyph.planeBounds.l = REAL(l);
|
||||
glyph.planeBounds.b = REAL(b);
|
||||
glyph.planeBounds.r = REAL(r);
|
||||
glyph.planeBounds.t = REAL(t);
|
||||
glyphGeom.getQuadAtlasBounds(l, b, r, t);
|
||||
glyph.imageBounds.l = REAL(l);
|
||||
glyph.imageBounds.b = REAL(b);
|
||||
glyph.imageBounds.r = REAL(r);
|
||||
glyph.imageBounds.t = REAL(t);
|
||||
glyph.advance.h = REAL(glyphGeom.getAdvance());
|
||||
glyph.advance.v = REAL(0);
|
||||
}
|
||||
switch (identifierType) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
for (const std::pair<std::pair<int, int>, double> &elem : font.getKerning()) {
|
||||
artery_font::KernPair<REAL> kernPair = { };
|
||||
kernPair.codepoint1 = elem.first.first;
|
||||
kernPair.codepoint2 = elem.first.second;
|
||||
kernPair.advance.h = REAL(elem.second);
|
||||
fontVariant.kernPairs.vector.push_back((artery_font::KernPair<REAL> &&) kernPair);
|
||||
}
|
||||
break;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
for (const std::pair<std::pair<int, int>, double> &elem : font.getKerning()) {
|
||||
const GlyphGeometry *glyph1 = font.getGlyph(msdfgen::GlyphIndex(elem.first.first));
|
||||
const GlyphGeometry *glyph2 = font.getGlyph(msdfgen::GlyphIndex(elem.first.second));
|
||||
if (glyph1 && glyph2 && glyph1->getCodepoint() && glyph2->getCodepoint()) {
|
||||
artery_font::KernPair<REAL> kernPair = { };
|
||||
kernPair.codepoint1 = glyph1->getCodepoint();
|
||||
kernPair.codepoint2 = glyph2->getCodepoint();
|
||||
kernPair.advance.h = REAL(elem.second);
|
||||
fontVariant.kernPairs.vector.push_back((artery_font::KernPair<REAL> &&) kernPair);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
arfont.variants.vector.push_back((artery_font::StdFontVariant<REAL> &&) fontVariant);
|
||||
}
|
||||
|
||||
{
|
||||
artery_font::StdImage image = { };
|
||||
image.width = atlas.width;
|
||||
image.height = atlas.height;
|
||||
image.channels = N;
|
||||
image.imageType = convertImageType(properties.imageType);
|
||||
switch (properties.imageFormat) {
|
||||
case ImageFormat::PNG:
|
||||
image.encoding = artery_font::IMAGE_PNG;
|
||||
image.pixelFormat = artery_font::PIXEL_UNSIGNED8;
|
||||
if (!encodePng(image.data.vector, atlas))
|
||||
return false;
|
||||
break;
|
||||
case ImageFormat::TIFF:
|
||||
image.encoding = artery_font::IMAGE_TIFF;
|
||||
image.pixelFormat = artery_font::PIXEL_FLOAT32;
|
||||
if (!encodeTiff(image.data.vector, atlas))
|
||||
return false;
|
||||
break;
|
||||
case ImageFormat::BINARY:
|
||||
image.pixelFormat = artery_font::PIXEL_UNSIGNED8;
|
||||
goto BINARY_EITHER;
|
||||
case ImageFormat::BINARY_FLOAT:
|
||||
image.pixelFormat = artery_font::PIXEL_FLOAT32;
|
||||
goto BINARY_EITHER;
|
||||
BINARY_EITHER:
|
||||
if (image.pixelFormat != getPixelFormat<T>())
|
||||
return false;
|
||||
image.encoding = artery_font::IMAGE_RAW_BINARY;
|
||||
image.rawBinaryFormat.rowLength = N*sizeof(T)*atlas.width;
|
||||
image.data = artery_font::StdByteArray(N*sizeof(T)*atlas.width*atlas.height);
|
||||
switch (properties.yDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
image.rawBinaryFormat.orientation = artery_font::ORIENTATION_BOTTOM_UP;
|
||||
memcpy((byte *) image.data, atlas.pixels, N*sizeof(T)*atlas.width*atlas.height);
|
||||
break;
|
||||
case YDirection::TOP_DOWN: {
|
||||
image.rawBinaryFormat.orientation = artery_font::ORIENTATION_TOP_DOWN;
|
||||
byte *imageData = (byte *) image.data;
|
||||
for (int y = atlas.height-1; y >= 0; --y) {
|
||||
memcpy(imageData, atlas.pixels+N*atlas.width*y, N*sizeof(T)*atlas.width);
|
||||
imageData += N*sizeof(T)*atlas.width;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
arfont.images.vector.push_back((artery_font::StdImage &&) image);
|
||||
}
|
||||
|
||||
return artery_font::writeFile(arfont, filename);
|
||||
}
|
||||
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<byte, 1> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<byte, 3> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<byte, 4> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<float, 1> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<float, 3> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
template bool exportArteryFont<float>(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<float, 4> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
|
||||
}
|
||||
*/
|
||||
23
Nuake/src/Vendors/msdf-atlas-gen/artery-font-export.h
Normal file
23
Nuake/src/Vendors/msdf-atlas-gen/artery-font-export.h
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include <msdfgen-ext.h>
|
||||
#include "types.h"
|
||||
#include "FontGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
struct ArteryFontExportProperties {
|
||||
double fontSize;
|
||||
double pxRange;
|
||||
ImageType imageType;
|
||||
ImageFormat imageFormat;
|
||||
YDirection yDirection;
|
||||
};
|
||||
|
||||
/// Encodes the atlas bitmap and its layout into an Artery Atlas Font file
|
||||
template <typename REAL, typename T, int N>
|
||||
bool exportArteryFont(const FontGeometry *fonts, int fontCount, const msdfgen::BitmapConstRef<T, N> &atlas, const char *filename, const ArteryFontExportProperties &properties);
|
||||
|
||||
}
|
||||
58
Nuake/src/Vendors/msdf-atlas-gen/bitmap-blit.cpp
Normal file
58
Nuake/src/Vendors/msdf-atlas-gen/bitmap-blit.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
#include "bitmap-blit.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
template <typename T, int N>
|
||||
void blitSameType(const msdfgen::BitmapRef<T, N> &dst, const msdfgen::BitmapConstRef<T, N> &src, int dx, int dy, int sx, int sy, int w, int h) {
|
||||
for (int y = 0; y < h; ++y)
|
||||
memcpy(dst(dx, dy+y), src(sx, sy+y), sizeof(T)*N*w);
|
||||
}
|
||||
|
||||
#define BLIT_SAME_TYPE_IMPL(T, N) void blit(const msdfgen::BitmapRef<T, N> &dst, const msdfgen::BitmapConstRef<T, N> &src, int dx, int dy, int sx, int sy, int w, int h) { blitSameType(dst, src, dx, dy, sx, sy, w, h); }
|
||||
|
||||
BLIT_SAME_TYPE_IMPL(byte, 1)
|
||||
BLIT_SAME_TYPE_IMPL(byte, 3)
|
||||
BLIT_SAME_TYPE_IMPL(byte, 4)
|
||||
BLIT_SAME_TYPE_IMPL(float, 1)
|
||||
BLIT_SAME_TYPE_IMPL(float, 3)
|
||||
BLIT_SAME_TYPE_IMPL(float, 4)
|
||||
|
||||
void blit(const msdfgen::BitmapRef<byte, 1> &dst, const msdfgen::BitmapConstRef<float, 1> &src, int dx, int dy, int sx, int sy, int w, int h) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
byte *dstPixel = dst(dx, dy+y);
|
||||
for (int x = 0; x < w; ++x) {
|
||||
const float *srcPixel = src(sx+x, sy+y);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(*srcPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blit(const msdfgen::BitmapRef<byte, 3> &dst, const msdfgen::BitmapConstRef<float, 3> &src, int dx, int dy, int sx, int sy, int w, int h) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
byte *dstPixel = dst(dx, dy+y);
|
||||
for (int x = 0; x < w; ++x) {
|
||||
const float *srcPixel = src(sx+x, sy+y);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[0]);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[1]);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void blit(const msdfgen::BitmapRef<byte, 4> &dst, const msdfgen::BitmapConstRef<float, 4> &src, int dx, int dy, int sx, int sy, int w, int h) {
|
||||
for (int y = 0; y < h; ++y) {
|
||||
byte *dstPixel = dst(dx, dy+y);
|
||||
for (int x = 0; x < w; ++x) {
|
||||
const float *srcPixel = src(sx+x, sy+y);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[0]);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[1]);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[2]);
|
||||
*dstPixel++ = msdfgen::pixelFloatToByte(srcPixel[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
Nuake/src/Vendors/msdf-atlas-gen/bitmap-blit.h
Normal file
26
Nuake/src/Vendors/msdf-atlas-gen/bitmap-blit.h
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include "types.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/*
|
||||
* Copies a rectangular section from source bitmap to destination bitmap.
|
||||
* Width and height are not checked and must not exceed bitmap bounds!
|
||||
*/
|
||||
|
||||
void blit(const msdfgen::BitmapRef<byte, 1> &dst, const msdfgen::BitmapConstRef<byte, 1> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<byte, 3> &dst, const msdfgen::BitmapConstRef<byte, 3> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<byte, 4> &dst, const msdfgen::BitmapConstRef<byte, 4> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
|
||||
void blit(const msdfgen::BitmapRef<float, 1> &dst, const msdfgen::BitmapConstRef<float, 1> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<float, 3> &dst, const msdfgen::BitmapConstRef<float, 3> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<float, 4> &dst, const msdfgen::BitmapConstRef<float, 4> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
|
||||
void blit(const msdfgen::BitmapRef<byte, 1> &dst, const msdfgen::BitmapConstRef<float, 1> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<byte, 3> &dst, const msdfgen::BitmapConstRef<float, 3> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
void blit(const msdfgen::BitmapRef<byte, 4> &dst, const msdfgen::BitmapConstRef<float, 4> &src, int dx, int dy, int sx, int sy, int w, int h);
|
||||
|
||||
}
|
||||
250
Nuake/src/Vendors/msdf-atlas-gen/charset-parser.cpp
Normal file
250
Nuake/src/Vendors/msdf-atlas-gen/charset-parser.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
|
||||
#include "Charset.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include "utf8.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
static char escapedChar(char c) {
|
||||
switch (c) {
|
||||
case '0':
|
||||
return '\0';
|
||||
case 'n': case 'N':
|
||||
return '\n';
|
||||
case 'r': case 'R':
|
||||
return '\r';
|
||||
case 's': case 'S':
|
||||
return ' ';
|
||||
case 't': case 'T':
|
||||
return '\t';
|
||||
case '\\': case '"': case '\'':
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static int readWord(std::string &str, FILE *f) {
|
||||
while (true) {
|
||||
int c = fgetc(f);
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_')
|
||||
str.push_back((char) c);
|
||||
else
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static bool readString(std::string &str, FILE *f, char terminator) {
|
||||
bool escape = false;
|
||||
while (true) {
|
||||
int c = fgetc(f);
|
||||
if (c < 0)
|
||||
return false;
|
||||
if (escape) {
|
||||
str.push_back(escapedChar((char) c));
|
||||
escape = false;
|
||||
} else {
|
||||
if (c == terminator)
|
||||
return true;
|
||||
else if (c == '\\')
|
||||
escape = true;
|
||||
else
|
||||
str.push_back((char) c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool parseInt(int &i, const char *str) {
|
||||
i = 0;
|
||||
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) { // hex
|
||||
str += 2;
|
||||
for (; *str; ++str) {
|
||||
if (*str >= '0' && *str <= '9') {
|
||||
i <<= 4;
|
||||
i += *str-'0';
|
||||
} else if (*str >= 'A' && *str <= 'F') {
|
||||
i <<= 4;
|
||||
i += *str-'A'+10;
|
||||
} else if (*str >= 'a' && *str <= 'f') {
|
||||
i <<= 4;
|
||||
i += *str-'a'+10;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
} else { // dec
|
||||
for (; *str; ++str) {
|
||||
if (*str >= '0' && *str <= '9') {
|
||||
i *= 10;
|
||||
i += *str-'0';
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::string combinePath(const char *basePath, const char *relPath) {
|
||||
if (relPath[0] == '/' || (relPath[0] && relPath[1] == ':')) // absolute path?
|
||||
return relPath;
|
||||
int lastSlash = -1;
|
||||
for (int i = 0; basePath[i]; ++i)
|
||||
if (basePath[i] == '/' || basePath[i] == '\\')
|
||||
lastSlash = i;
|
||||
if (lastSlash < 0)
|
||||
return relPath;
|
||||
return std::string(basePath, lastSlash+1)+relPath;
|
||||
}
|
||||
|
||||
bool Charset::load(const char *filename, bool disableCharLiterals) {
|
||||
|
||||
if (FILE *f = fopen(filename, "rb")) {
|
||||
|
||||
enum {
|
||||
CLEAR,
|
||||
TIGHT,
|
||||
RANGE_BRACKET,
|
||||
RANGE_START,
|
||||
RANGE_SEPARATOR,
|
||||
RANGE_END
|
||||
} state = CLEAR;
|
||||
|
||||
std::string buffer;
|
||||
std::vector<unicode_t> unicodeBuffer;
|
||||
unicode_t rangeStart = 0;
|
||||
for (int c = fgetc(f), start = true; c >= 0; start = false) {
|
||||
switch (c) {
|
||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // number
|
||||
if (!(state == CLEAR || state == RANGE_BRACKET || state == RANGE_SEPARATOR))
|
||||
goto FAIL;
|
||||
buffer.push_back((char) c);
|
||||
c = readWord(buffer, f);
|
||||
{
|
||||
int cp;
|
||||
if (!parseInt(cp, buffer.c_str()))
|
||||
goto FAIL;
|
||||
switch (state) {
|
||||
case CLEAR:
|
||||
if (cp >= 0)
|
||||
add((unicode_t) cp);
|
||||
state = TIGHT;
|
||||
break;
|
||||
case RANGE_BRACKET:
|
||||
rangeStart = (unicode_t) cp;
|
||||
state = RANGE_START;
|
||||
break;
|
||||
case RANGE_SEPARATOR:
|
||||
for (unicode_t u = rangeStart; (int) u <= cp; ++u)
|
||||
add(u);
|
||||
state = RANGE_END;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
buffer.clear();
|
||||
continue; // next character already read
|
||||
case '\'': // single UTF-8 character
|
||||
if (!(state == CLEAR || state == RANGE_BRACKET || state == RANGE_SEPARATOR) || disableCharLiterals)
|
||||
goto FAIL;
|
||||
if (!readString(buffer, f, '\''))
|
||||
goto FAIL;
|
||||
utf8Decode(unicodeBuffer, buffer.c_str());
|
||||
if (unicodeBuffer.size() == 1) {
|
||||
switch (state) {
|
||||
case CLEAR:
|
||||
if (unicodeBuffer[0] > 0)
|
||||
add(unicodeBuffer[0]);
|
||||
state = TIGHT;
|
||||
break;
|
||||
case RANGE_BRACKET:
|
||||
rangeStart = unicodeBuffer[0];
|
||||
state = RANGE_START;
|
||||
break;
|
||||
case RANGE_SEPARATOR:
|
||||
for (unicode_t u = rangeStart; u <= unicodeBuffer[0]; ++u)
|
||||
add(u);
|
||||
state = RANGE_END;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
} else
|
||||
goto FAIL;
|
||||
unicodeBuffer.clear();
|
||||
buffer.clear();
|
||||
break;
|
||||
case '"': // string of UTF-8 characters
|
||||
if (state != CLEAR || disableCharLiterals)
|
||||
goto FAIL;
|
||||
if (!readString(buffer, f, '"'))
|
||||
goto FAIL;
|
||||
utf8Decode(unicodeBuffer, buffer.c_str());
|
||||
for (unicode_t cp : unicodeBuffer)
|
||||
add(cp);
|
||||
unicodeBuffer.clear();
|
||||
buffer.clear();
|
||||
state = TIGHT;
|
||||
break;
|
||||
case '[': // character range start
|
||||
if (state != CLEAR)
|
||||
goto FAIL;
|
||||
state = RANGE_BRACKET;
|
||||
break;
|
||||
case ']': // character range end
|
||||
if (state == RANGE_END)
|
||||
state = TIGHT;
|
||||
else
|
||||
goto FAIL;
|
||||
break;
|
||||
case '@': // annotation
|
||||
if (state != CLEAR)
|
||||
goto FAIL;
|
||||
c = readWord(buffer, f);
|
||||
if (buffer == "include") {
|
||||
while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
|
||||
c = fgetc(f);
|
||||
if (c != '"')
|
||||
goto FAIL;
|
||||
buffer.clear();
|
||||
if (!readString(buffer, f, '"'))
|
||||
goto FAIL;
|
||||
load(combinePath(filename, buffer.c_str()).c_str());
|
||||
state = TIGHT;
|
||||
} else
|
||||
goto FAIL;
|
||||
buffer.clear();
|
||||
break;
|
||||
case ',': case ';': // separator
|
||||
if (!(state == CLEAR || state == TIGHT)) {
|
||||
if (state == RANGE_START)
|
||||
state = RANGE_SEPARATOR;
|
||||
else
|
||||
goto FAIL;
|
||||
} // else treat as whitespace
|
||||
case ' ': case '\n': case '\r': case '\t': // whitespace
|
||||
if (state == TIGHT)
|
||||
state = CLEAR;
|
||||
break;
|
||||
case 0xef: // UTF-8 byte order mark
|
||||
if (start) {
|
||||
if (!(fgetc(f) == 0xbb && fgetc(f) == 0xbf))
|
||||
goto FAIL;
|
||||
break;
|
||||
}
|
||||
default: // unexpected character
|
||||
goto FAIL;
|
||||
}
|
||||
c = fgetc(f);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return state == CLEAR || state == TIGHT;
|
||||
|
||||
FAIL:
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
45
Nuake/src/Vendors/msdf-atlas-gen/csv-export.cpp
Normal file
45
Nuake/src/Vendors/msdf-atlas-gen/csv-export.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
|
||||
#include "csv-export.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include "GlyphGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
bool exportCSV(const FontGeometry *fonts, int fontCount, int atlasWidth, int atlasHeight, YDirection yDirection, const char *filename) {
|
||||
FILE *f = fopen(filename, "w");
|
||||
if (!f)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < fontCount; ++i) {
|
||||
for (const GlyphGeometry &glyph : fonts[i].getGlyphs()) {
|
||||
double l, b, r, t;
|
||||
if (fontCount > 1)
|
||||
fprintf(f, "%d,", i);
|
||||
fprintf(f, "%d,%.17g,", glyph.getIdentifier(fonts[i].getPreferredIdentifierType()), glyph.getAdvance());
|
||||
glyph.getQuadPlaneBounds(l, b, r, t);
|
||||
switch (yDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g,", l, b, r, t);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g,", l, -t, r, -b);
|
||||
break;
|
||||
}
|
||||
glyph.getQuadAtlasBounds(l, b, r, t);
|
||||
switch (yDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g\n", l, b, r, t);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
fprintf(f, "%.17g,%.17g,%.17g,%.17g\n", l, atlasHeight-t, r, atlasHeight-b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
14
Nuake/src/Vendors/msdf-atlas-gen/csv-export.h
Normal file
14
Nuake/src/Vendors/msdf-atlas-gen/csv-export.h
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FontGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/**
|
||||
* Writes the positioning data and atlas layout of the glyphs into a CSV file
|
||||
* The columns are: font variant index (if fontCount > 1), glyph identifier (index or Unicode), horizontal advance, plane bounds (l, b, r, t), atlas bounds (l, b, r, t)
|
||||
*/
|
||||
bool exportCSV(const FontGeometry *fonts, int fontCount, int atlasWidth, int atlasHeight, YDirection yDirection, const char *filename);
|
||||
|
||||
}
|
||||
52
Nuake/src/Vendors/msdf-atlas-gen/glyph-generators.cpp
Normal file
52
Nuake/src/Vendors/msdf-atlas-gen/glyph-generators.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
#include "glyph-generators.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
void scanlineGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs) {
|
||||
msdfgen::rasterize(output, glyph.getShape(), glyph.getBoxScale(), glyph.getBoxTranslate(), MSDF_ATLAS_GLYPH_FILL_RULE);
|
||||
}
|
||||
|
||||
void sdfGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs) {
|
||||
msdfgen::generateSDF(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), attribs.config);
|
||||
if (attribs.scanlinePass)
|
||||
msdfgen::distanceSignCorrection(output, glyph.getShape(), glyph.getBoxProjection(), MSDF_ATLAS_GLYPH_FILL_RULE);
|
||||
}
|
||||
|
||||
void psdfGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs) {
|
||||
msdfgen::generatePseudoSDF(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), attribs.config);
|
||||
if (attribs.scanlinePass)
|
||||
msdfgen::distanceSignCorrection(output, glyph.getShape(), glyph.getBoxProjection(), MSDF_ATLAS_GLYPH_FILL_RULE);
|
||||
}
|
||||
|
||||
void msdfGenerator(const msdfgen::BitmapRef<float, 3> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs) {
|
||||
msdfgen::MSDFGeneratorConfig config = attribs.config;
|
||||
if (attribs.scanlinePass)
|
||||
config.errorCorrection.mode = msdfgen::ErrorCorrectionConfig::DISABLED;
|
||||
msdfgen::generateMSDF(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), config);
|
||||
if (attribs.scanlinePass) {
|
||||
msdfgen::distanceSignCorrection(output, glyph.getShape(), glyph.getBoxProjection(), MSDF_ATLAS_GLYPH_FILL_RULE);
|
||||
if (attribs.config.errorCorrection.mode != msdfgen::ErrorCorrectionConfig::DISABLED) {
|
||||
config.errorCorrection.mode = attribs.config.errorCorrection.mode;
|
||||
config.errorCorrection.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
msdfgen::msdfErrorCorrection(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mtsdfGenerator(const msdfgen::BitmapRef<float, 4> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs) {
|
||||
msdfgen::MSDFGeneratorConfig config = attribs.config;
|
||||
if (attribs.scanlinePass)
|
||||
config.errorCorrection.mode = msdfgen::ErrorCorrectionConfig::DISABLED;
|
||||
msdfgen::generateMTSDF(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), config);
|
||||
if (attribs.scanlinePass) {
|
||||
msdfgen::distanceSignCorrection(output, glyph.getShape(), glyph.getBoxProjection(), MSDF_ATLAS_GLYPH_FILL_RULE);
|
||||
if (attribs.config.errorCorrection.mode != msdfgen::ErrorCorrectionConfig::DISABLED) {
|
||||
config.errorCorrection.mode = attribs.config.errorCorrection.mode;
|
||||
config.errorCorrection.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
msdfgen::msdfErrorCorrection(output, glyph.getShape(), glyph.getBoxProjection(), glyph.getBoxRange(), config);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
25
Nuake/src/Vendors/msdf-atlas-gen/glyph-generators.h
Normal file
25
Nuake/src/Vendors/msdf-atlas-gen/glyph-generators.h
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include "GlyphGeometry.h"
|
||||
#include "AtlasGenerator.h"
|
||||
|
||||
#define MSDF_ATLAS_GLYPH_FILL_RULE msdfgen::FILL_NONZERO
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
// Glyph bitmap generator functions
|
||||
|
||||
/// Generates non-anti-aliased binary image of the glyph using scanline rasterization
|
||||
void scanlineGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs);
|
||||
/// Generates a true signed distance field of the glyph
|
||||
void sdfGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs);
|
||||
/// Generates a signed pseudo-distance field of the glyph
|
||||
void psdfGenerator(const msdfgen::BitmapRef<float, 1> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs);
|
||||
/// Generates a multi-channel signed distance field of the glyph
|
||||
void msdfGenerator(const msdfgen::BitmapRef<float, 3> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs);
|
||||
/// Generates a multi-channel and alpha-encoded true signed distance field of the glyph
|
||||
void mtsdfGenerator(const msdfgen::BitmapRef<float, 4> &output, const GlyphGeometry &glyph, const GeneratorAttributes &attribs);
|
||||
|
||||
}
|
||||
BIN
Nuake/src/Vendors/msdf-atlas-gen/icon.ico
Normal file
BIN
Nuake/src/Vendors/msdf-atlas-gen/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
63
Nuake/src/Vendors/msdf-atlas-gen/image-encode.cpp
Normal file
63
Nuake/src/Vendors/msdf-atlas-gen/image-encode.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
|
||||
#include "image-encode.h"
|
||||
|
||||
#include <lodepng.h>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 1> &bitmap) {
|
||||
std::vector<byte> pixels(bitmap.width*bitmap.height);
|
||||
for (int y = 0; y < bitmap.height; ++y)
|
||||
memcpy(&pixels[bitmap.width*y], bitmap(0, bitmap.height-y-1), bitmap.width);
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_GREY);
|
||||
}
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 3> &bitmap) {
|
||||
std::vector<byte> pixels(3*bitmap.width*bitmap.height);
|
||||
for (int y = 0; y < bitmap.height; ++y)
|
||||
memcpy(&pixels[3*bitmap.width*y], bitmap(0, bitmap.height-y-1), 3*bitmap.width);
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_RGB);
|
||||
}
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 4> &bitmap) {
|
||||
std::vector<byte> pixels(4*bitmap.width*bitmap.height);
|
||||
for (int y = 0; y < bitmap.height; ++y)
|
||||
memcpy(&pixels[4*bitmap.width*y], bitmap(0, bitmap.height-y-1), 4*bitmap.width);
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_RGBA);
|
||||
}
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 1> &bitmap) {
|
||||
std::vector<byte> pixels(bitmap.width*bitmap.height);
|
||||
std::vector<byte>::iterator it = pixels.begin();
|
||||
for (int y = bitmap.height-1; y >= 0; --y)
|
||||
for (int x = 0; x < bitmap.width; ++x)
|
||||
*it++ = msdfgen::pixelFloatToByte(*bitmap(x, y));
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_GREY);
|
||||
}
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 3> &bitmap) {
|
||||
std::vector<byte> pixels(3*bitmap.width*bitmap.height);
|
||||
std::vector<byte>::iterator it = pixels.begin();
|
||||
for (int y = bitmap.height-1; y >= 0; --y)
|
||||
for (int x = 0; x < bitmap.width; ++x) {
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[0]);
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[1]);
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[2]);
|
||||
}
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_RGB);
|
||||
}
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 4> &bitmap) {
|
||||
std::vector<byte> pixels(4*bitmap.width*bitmap.height);
|
||||
std::vector<byte>::iterator it = pixels.begin();
|
||||
for (int y = bitmap.height-1; y >= 0; --y)
|
||||
for (int x = 0; x < bitmap.width; ++x) {
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[0]);
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[1]);
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[2]);
|
||||
*it++ = msdfgen::pixelFloatToByte(bitmap(x, y)[3]);
|
||||
}
|
||||
return !lodepng::encode(output, pixels, bitmap.width, bitmap.height, LCT_RGBA);
|
||||
}
|
||||
|
||||
}
|
||||
20
Nuake/src/Vendors/msdf-atlas-gen/image-encode.h
Normal file
20
Nuake/src/Vendors/msdf-atlas-gen/image-encode.h
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <msdfgen.h>
|
||||
#include "types.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
// Functions to encode an image as a sequence of bytes in memory
|
||||
// Only PNG format available currently
|
||||
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 1> &bitmap);
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 3> &bitmap);
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<msdfgen::byte, 4> &bitmap);
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 1> &bitmap);
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 3> &bitmap);
|
||||
bool encodePng(std::vector<byte> &output, const msdfgen::BitmapConstRef<float, 4> &bitmap);
|
||||
|
||||
}
|
||||
15
Nuake/src/Vendors/msdf-atlas-gen/image-save.h
Normal file
15
Nuake/src/Vendors/msdf-atlas-gen/image-save.h
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include "types.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Saves the bitmap as an image file with the specified format
|
||||
template <typename T, int N>
|
||||
bool saveImage(const msdfgen::BitmapConstRef<T, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection = YDirection::BOTTOM_UP);
|
||||
|
||||
}
|
||||
|
||||
#include "image-save.hpp"
|
||||
172
Nuake/src/Vendors/msdf-atlas-gen/image-save.hpp
Normal file
172
Nuake/src/Vendors/msdf-atlas-gen/image-save.hpp
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
#include "image-save.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <msdfgen-ext.h>
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
template <int N>
|
||||
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||
template <int N>
|
||||
bool saveImageBinaryLE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||
template <int N>
|
||||
bool saveImageBinaryBE(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||
|
||||
template <int N>
|
||||
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||
template <int N>
|
||||
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection);
|
||||
|
||||
template <int N>
|
||||
bool saveImage(const msdfgen::BitmapConstRef<byte, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection) {
|
||||
switch (format) {
|
||||
//case ImageFormat::PNG:
|
||||
// return msdfgen::savePng(bitmap, filename);
|
||||
case ImageFormat::BMP:
|
||||
return msdfgen::saveBmp(bitmap, filename);
|
||||
case ImageFormat::TIFF:
|
||||
return false;
|
||||
case ImageFormat::TEXT:
|
||||
return saveImageText(bitmap, filename, outputYDirection);
|
||||
case ImageFormat::TEXT_FLOAT:
|
||||
return false;
|
||||
case ImageFormat::BINARY:
|
||||
return saveImageBinary(bitmap, filename, outputYDirection);
|
||||
case ImageFormat::BINARY_FLOAT:
|
||||
case ImageFormat::BINARY_FLOAT_BE:
|
||||
return false;
|
||||
default:;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
bool saveImage(const msdfgen::BitmapConstRef<float, N> &bitmap, ImageFormat format, const char *filename, YDirection outputYDirection) {
|
||||
switch (format) {
|
||||
case ImageFormat::PNG:
|
||||
return msdfgen::savePng(bitmap, filename);
|
||||
case ImageFormat::BMP:
|
||||
return msdfgen::saveBmp(bitmap, filename);
|
||||
case ImageFormat::TIFF:
|
||||
return msdfgen::saveTiff(bitmap, filename);
|
||||
case ImageFormat::TEXT:
|
||||
return false;
|
||||
case ImageFormat::TEXT_FLOAT:
|
||||
return saveImageText(bitmap, filename, outputYDirection);
|
||||
case ImageFormat::BINARY:
|
||||
return false;
|
||||
case ImageFormat::BINARY_FLOAT:
|
||||
return saveImageBinaryLE(bitmap, filename, outputYDirection);
|
||||
case ImageFormat::BINARY_FLOAT_BE:
|
||||
return saveImageBinaryBE(bitmap, filename, outputYDirection);
|
||||
default:;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
bool saveImageBinary(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||
bool success = false;
|
||||
if (FILE *f = fopen(filename, "wb")) {
|
||||
int written = 0;
|
||||
switch (outputYDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
written = fwrite(bitmap.pixels, 1, N*bitmap.width*bitmap.height, f);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
for (int y = bitmap.height-1; y >= 0; --y)
|
||||
written += fwrite(bitmap.pixels+N*bitmap.width*y, 1, N*bitmap.width, f);
|
||||
break;
|
||||
}
|
||||
success = written == N*bitmap.width*bitmap.height;
|
||||
fclose(f);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
bool
|
||||
#ifdef __BIG_ENDIAN__
|
||||
saveImageBinaryBE
|
||||
#else
|
||||
saveImageBinaryLE
|
||||
#endif
|
||||
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||
bool success = false;
|
||||
if (FILE *f = fopen(filename, "wb")) {
|
||||
int written = 0;
|
||||
switch (outputYDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
written = fwrite(bitmap.pixels, sizeof(float), N*bitmap.width*bitmap.height, f);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
for (int y = bitmap.height-1; y >= 0; --y)
|
||||
written += fwrite(bitmap.pixels+N*bitmap.width*y, sizeof(float), N*bitmap.width, f);
|
||||
break;
|
||||
}
|
||||
success = written == N*bitmap.width*bitmap.height;
|
||||
fclose(f);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
bool
|
||||
#ifdef __BIG_ENDIAN__
|
||||
saveImageBinaryLE
|
||||
#else
|
||||
saveImageBinaryBE
|
||||
#endif
|
||||
(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||
bool success = false;
|
||||
if (FILE *f = fopen(filename, "wb")) {
|
||||
int written = 0;
|
||||
for (int y = 0; y < bitmap.height; ++y) {
|
||||
const float *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
|
||||
for (int x = 0; x < bitmap.width; ++x) {
|
||||
const unsigned char *b = reinterpret_cast<const unsigned char *>(p++);
|
||||
for (int i = sizeof(float)-1; i >= 0; --i)
|
||||
written += fwrite(b+i, 1, 1, f);
|
||||
}
|
||||
}
|
||||
success = written == sizeof(float)*N*bitmap.width*bitmap.height;
|
||||
fclose(f);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
template <int N>
|
||||
bool saveImageText(const msdfgen::BitmapConstRef<byte, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||
bool success = false;
|
||||
if (FILE *f = fopen(filename, "wb")) {
|
||||
for (int y = 0; y < bitmap.height; ++y) {
|
||||
const byte *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
|
||||
for (int x = 0; x < N*bitmap.width; ++x) {
|
||||
fprintf(f, x ? " %02X" : "%02X", (unsigned) *p++);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
template <int N>
|
||||
bool saveImageText(const msdfgen::BitmapConstRef<float, N> &bitmap, const char *filename, YDirection outputYDirection) {
|
||||
bool success = false;
|
||||
if (FILE *f = fopen(filename, "wb")) {
|
||||
for (int y = 0; y < bitmap.height; ++y) {
|
||||
const float *p = bitmap.pixels+N*bitmap.width*(outputYDirection == YDirection::TOP_DOWN ? bitmap.height-y-1 : y);
|
||||
for (int x = 0; x < N*bitmap.width; ++x) {
|
||||
fprintf(f, x ? " %g" : "%g", *p++);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
186
Nuake/src/Vendors/msdf-atlas-gen/json-export.cpp
Normal file
186
Nuake/src/Vendors/msdf-atlas-gen/json-export.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
|
||||
#include "json-export.h"
|
||||
|
||||
#include <string>
|
||||
#include "GlyphGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
static std::string escapeJsonString(const char *str) {
|
||||
char uval[7] = "\\u0000";
|
||||
std::string outStr;
|
||||
while (*str) {
|
||||
switch (*str) {
|
||||
case '\\':
|
||||
outStr += "\\\\";
|
||||
break;
|
||||
case '"':
|
||||
outStr += "\\\"";
|
||||
break;
|
||||
case '\n':
|
||||
outStr += "\\n";
|
||||
break;
|
||||
case '\r':
|
||||
outStr += "\\r";
|
||||
break;
|
||||
case '\t':
|
||||
outStr += "\\t";
|
||||
break;
|
||||
case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: /* \\t */ /* \\n */ case 0x0b: case 0x0c: /* \\r */ case 0x0e: case 0x0f:
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
|
||||
uval[4] = '0'+(*str >= 0x10);
|
||||
uval[5] = "0123456789abcdef"[*str&0x0f];
|
||||
outStr += uval;
|
||||
break;
|
||||
default:
|
||||
outStr.push_back(*str);
|
||||
}
|
||||
++str;
|
||||
}
|
||||
return outStr;
|
||||
}
|
||||
|
||||
static const char * imageTypeString(ImageType type) {
|
||||
switch (type) {
|
||||
case ImageType::HARD_MASK:
|
||||
return "hardmask";
|
||||
case ImageType::SOFT_MASK:
|
||||
return "softmask";
|
||||
case ImageType::SDF:
|
||||
return "sdf";
|
||||
case ImageType::PSDF:
|
||||
return "psdf";
|
||||
case ImageType::MSDF:
|
||||
return "msdf";
|
||||
case ImageType::MTSDF:
|
||||
return "mtsdf";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, YDirection yDirection, const char *filename, bool kerning) {
|
||||
FILE *f = fopen(filename, "w");
|
||||
if (!f)
|
||||
return false;
|
||||
fputs("{", f);
|
||||
|
||||
// Atlas properties
|
||||
fputs("\"atlas\":{", f); {
|
||||
fprintf(f, "\"type\":\"%s\",", imageTypeString(imageType));
|
||||
if (imageType == ImageType::SDF || imageType == ImageType::PSDF || imageType == ImageType::MSDF || imageType == ImageType::MTSDF)
|
||||
fprintf(f, "\"distanceRange\":%.17g,", pxRange);
|
||||
fprintf(f, "\"size\":%.17g,", fontSize);
|
||||
fprintf(f, "\"width\":%d,", atlasWidth);
|
||||
fprintf(f, "\"height\":%d,", atlasHeight);
|
||||
fprintf(f, "\"yOrigin\":\"%s\"", yDirection == YDirection::TOP_DOWN ? "top" : "bottom");
|
||||
} fputs("},", f);
|
||||
|
||||
if (fontCount > 1)
|
||||
fputs("\"variants\":[", f);
|
||||
for (int i = 0; i < fontCount; ++i) {
|
||||
const FontGeometry &font = fonts[i];
|
||||
if (fontCount > 1)
|
||||
fputs(i == 0 ? "{" : ",{", f);
|
||||
|
||||
// Font name
|
||||
const char *name = font.getName();
|
||||
if (name)
|
||||
fprintf(f, "\"name\":\"%s\",", escapeJsonString(name).c_str());
|
||||
|
||||
// Font metrics
|
||||
fputs("\"metrics\":{", f); {
|
||||
double yFactor = yDirection == YDirection::TOP_DOWN ? -1 : 1;
|
||||
const msdfgen::FontMetrics &metrics = font.getMetrics();
|
||||
fprintf(f, "\"emSize\":%.17g,", metrics.emSize);
|
||||
fprintf(f, "\"lineHeight\":%.17g,", metrics.lineHeight);
|
||||
fprintf(f, "\"ascender\":%.17g,", yFactor*metrics.ascenderY);
|
||||
fprintf(f, "\"descender\":%.17g,", yFactor*metrics.descenderY);
|
||||
fprintf(f, "\"underlineY\":%.17g,", yFactor*metrics.underlineY);
|
||||
fprintf(f, "\"underlineThickness\":%.17g", metrics.underlineThickness);
|
||||
} fputs("},", f);
|
||||
|
||||
// Glyph mapping
|
||||
fputs("\"glyphs\":[", f);
|
||||
bool firstGlyph = true;
|
||||
for (const GlyphGeometry &glyph : font.getGlyphs()) {
|
||||
fputs(firstGlyph ? "{" : ",{", f);
|
||||
switch (font.getPreferredIdentifierType()) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
fprintf(f, "\"index\":%d,", glyph.getIndex());
|
||||
break;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
fprintf(f, "\"unicode\":%u,", glyph.getCodepoint());
|
||||
break;
|
||||
}
|
||||
fprintf(f, "\"advance\":%.17g", glyph.getAdvance());
|
||||
double l, b, r, t;
|
||||
glyph.getQuadPlaneBounds(l, b, r, t);
|
||||
if (l || b || r || t) {
|
||||
switch (yDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
fprintf(f, ",\"planeBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
fprintf(f, ",\"planeBounds\":{\"left\":%.17g,\"top\":%.17g,\"right\":%.17g,\"bottom\":%.17g}", l, -t, r, -b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
glyph.getQuadAtlasBounds(l, b, r, t);
|
||||
if (l || b || r || t) {
|
||||
switch (yDirection) {
|
||||
case YDirection::BOTTOM_UP:
|
||||
fprintf(f, ",\"atlasBounds\":{\"left\":%.17g,\"bottom\":%.17g,\"right\":%.17g,\"top\":%.17g}", l, b, r, t);
|
||||
break;
|
||||
case YDirection::TOP_DOWN:
|
||||
fprintf(f, ",\"atlasBounds\":{\"left\":%.17g,\"top\":%.17g,\"right\":%.17g,\"bottom\":%.17g}", l, atlasHeight-t, r, atlasHeight-b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fputs("}", f);
|
||||
firstGlyph = false;
|
||||
} fputs("]", f);
|
||||
|
||||
// Kerning pairs
|
||||
if (kerning) {
|
||||
fputs(",\"kerning\":[", f);
|
||||
bool firstPair = true;
|
||||
switch (font.getPreferredIdentifierType()) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
for (const std::pair<std::pair<int, int>, double> &kernPair : font.getKerning()) {
|
||||
fputs(firstPair ? "{" : ",{", f);
|
||||
fprintf(f, "\"index1\":%d,", kernPair.first.first);
|
||||
fprintf(f, "\"index2\":%d,", kernPair.first.second);
|
||||
fprintf(f, "\"advance\":%.17g", kernPair.second);
|
||||
fputs("}", f);
|
||||
firstPair = false;
|
||||
}
|
||||
break;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
for (const std::pair<std::pair<int, int>, double> &kernPair : font.getKerning()) {
|
||||
const GlyphGeometry *glyph1 = font.getGlyph(msdfgen::GlyphIndex(kernPair.first.first));
|
||||
const GlyphGeometry *glyph2 = font.getGlyph(msdfgen::GlyphIndex(kernPair.first.second));
|
||||
if (glyph1 && glyph2 && glyph1->getCodepoint() && glyph2->getCodepoint()) {
|
||||
fputs(firstPair ? "{" : ",{", f);
|
||||
fprintf(f, "\"unicode1\":%u,", glyph1->getCodepoint());
|
||||
fprintf(f, "\"unicode2\":%u,", glyph2->getCodepoint());
|
||||
fprintf(f, "\"advance\":%.17g", kernPair.second);
|
||||
fputs("}", f);
|
||||
firstPair = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} fputs("]", f);
|
||||
}
|
||||
|
||||
if (fontCount > 1)
|
||||
fputs("}", f);
|
||||
}
|
||||
if (fontCount > 1)
|
||||
fputs("]", f);
|
||||
|
||||
fputs("}\n", f);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
14
Nuake/src/Vendors/msdf-atlas-gen/json-export.h
Normal file
14
Nuake/src/Vendors/msdf-atlas-gen/json-export.h
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include <msdfgen-ext.h>
|
||||
#include "types.h"
|
||||
#include "FontGeometry.h"
|
||||
|
||||
namespace msdf_atlas {
|
||||
|
||||
/// Writes the font and glyph metrics and atlas layout data into a comprehensive JSON file
|
||||
bool exportJSON(const FontGeometry *fonts, int fontCount, double fontSize, double pxRange, int atlasWidth, int atlasHeight, ImageType imageType, YDirection yDirection, const char *filename, bool kerning);
|
||||
|
||||
}
|
||||
999
Nuake/src/Vendors/msdf-atlas-gen/main.cpp
Normal file
999
Nuake/src/Vendors/msdf-atlas-gen/main.cpp
Normal file
@@ -0,0 +1,999 @@
|
||||
|
||||
/*
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD ATLAS GENERATOR v1.2 (2021-05-29) - standalone console program
|
||||
* --------------------------------------------------------------------------------------------------
|
||||
* A utility by Viktor Chlumsky, (c) 2020 - 2021
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef MSDF_ATLAS_STANDALONE
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
|
||||
#include "msdf-atlas-gen.h"
|
||||
|
||||
using namespace msdf_atlas;
|
||||
|
||||
#define DEFAULT_ANGLE_THRESHOLD 3.0
|
||||
#define DEFAULT_MITER_LIMIT 1.0
|
||||
#define DEFAULT_PIXEL_RANGE 2.0
|
||||
#define SDF_ERROR_ESTIMATE_PRECISION 19
|
||||
#define GLYPH_FILL_RULE msdfgen::FILL_NONZERO
|
||||
#define LCG_MULTIPLIER 6364136223846793005ull
|
||||
#define LCG_INCREMENT 1442695040888963407ull
|
||||
|
||||
#ifdef MSDFGEN_USE_SKIA
|
||||
#define TITLE_SUFFIX " & Skia"
|
||||
#define EXTRA_UNDERLINE "-------"
|
||||
#else
|
||||
#define TITLE_SUFFIX
|
||||
#define EXTRA_UNDERLINE
|
||||
#endif
|
||||
|
||||
static const char * const helpText = R"(
|
||||
MSDF Atlas Generator by Viktor Chlumsky v)" MSDF_ATLAS_VERSION R"( (with MSDFGEN v)" MSDFGEN_VERSION TITLE_SUFFIX R"()
|
||||
----------------------------------------------------------------)" EXTRA_UNDERLINE R"(
|
||||
|
||||
INPUT SPECIFICATION
|
||||
-font <filename.ttf/otf>
|
||||
Specifies the input TrueType / OpenType font file. This is required.
|
||||
-charset <filename>
|
||||
Specifies the input character set. Refer to the documentation for format of charset specification. Defaults to ASCII.
|
||||
-glyphset <filename>
|
||||
Specifies the set of input glyphs as glyph indices within the font file.
|
||||
-fontscale <scale>
|
||||
Specifies the scale to be applied to the glyph geometry of the font.
|
||||
-fontname <name>
|
||||
Specifies a name for the font that will be propagated into the output files as metadata.
|
||||
-and
|
||||
Separates multiple inputs to be combined into a single atlas.
|
||||
|
||||
ATLAS CONFIGURATION
|
||||
-type <hardmask / softmask / sdf / psdf / msdf / mtsdf>
|
||||
Selects the type of atlas to be generated.
|
||||
-format <png / bmp / tiff / text / textfloat / bin / binfloat / binfloatbe>
|
||||
Selects the format for the atlas image output. Some image formats may be incompatible with embedded output formats.
|
||||
-dimensions <width> <height>
|
||||
Sets the atlas to have fixed dimensions (width x height).
|
||||
-pots / -potr / -square / -square2 / -square4
|
||||
Picks the minimum atlas dimensions that fit all glyphs and satisfy the selected constraint:
|
||||
power of two square / ... rectangle / any square / square with side divisible by 2 / ... 4
|
||||
-yorigin <bottom / top>
|
||||
Determines whether the Y-axis is oriented upwards (bottom origin, default) or downwards (top origin).
|
||||
|
||||
OUTPUT SPECIFICATION - one or more can be specified
|
||||
-imageout <filename.*>
|
||||
Saves the atlas as an image file with the specified format. Layout data must be stored separately.
|
||||
-json <filename.json>
|
||||
Writes the atlas's layout data, as well as other metrics into a structured JSON file.
|
||||
-csv <filename.csv>
|
||||
Writes the layout data of the glyphs into a simple CSV file.
|
||||
-arfont <filename.arfont>
|
||||
Stores the atlas and its layout data as an Artery Font file. Supported formats: png, bin, binfloat.
|
||||
-shadronpreview <filename.shadron> <sample text>
|
||||
Generates a Shadron script that uses the generated atlas to draw a sample text as a preview.
|
||||
|
||||
GLYPH CONFIGURATION
|
||||
-size <EM size>
|
||||
Specifies the size of the glyphs in the atlas bitmap in pixels per EM.
|
||||
-minsize <EM size>
|
||||
Specifies the minimum size. The largest possible size that fits the same atlas dimensions will be used.
|
||||
-emrange <EM range>
|
||||
Specifies the SDF distance range in EM's.
|
||||
-pxrange <pixel range>
|
||||
Specifies the SDF distance range in output pixels. The default value is 2.
|
||||
-nokerning
|
||||
Disables inclusion of kerning pair table in output files.
|
||||
|
||||
DISTANCE FIELD GENERATOR SETTINGS
|
||||
-angle <angle>
|
||||
Specifies the minimum angle between adjacent edges to be considered a corner. Append D for degrees. (msdf / mtsdf only)
|
||||
-coloringstrategy <simple / inktrap / distance>
|
||||
Selects the strategy of the edge coloring heuristic.
|
||||
-errorcorrection <mode>
|
||||
Changes the MSDF/MTSDF error correction mode. Use -errorcorrection help for a list of valid modes.
|
||||
-errordeviationratio <ratio>
|
||||
Sets the minimum ratio between the actual and maximum expected distance delta to be considered an error.
|
||||
-errorimproveratio <ratio>
|
||||
Sets the minimum ratio between the pre-correction distance error and the post-correction distance error.
|
||||
-miterlimit <value>
|
||||
Sets the miter limit that limits the extension of each glyph's bounding box due to very sharp corners. (psdf / msdf / mtsdf only))"
|
||||
#ifdef MSDFGEN_USE_SKIA
|
||||
R"(
|
||||
-overlap
|
||||
Switches to distance field generator with support for overlapping contours.
|
||||
-nopreprocess
|
||||
Disables path preprocessing which resolves self-intersections and overlapping contours.
|
||||
-scanline
|
||||
Performs an additional scanline pass to fix the signs of the distances.)"
|
||||
#else
|
||||
R"(
|
||||
-nooverlap
|
||||
Disables resolution of overlapping contours.
|
||||
-noscanline
|
||||
Disables the scanline pass, which corrects the distance field's signs according to the non-zero fill rule.)"
|
||||
#endif
|
||||
R"(
|
||||
-seed <N>
|
||||
Sets the initial seed for the edge coloring heuristic.
|
||||
-threads <N>
|
||||
Sets the number of threads for the parallel computation. (0 = auto)
|
||||
)";
|
||||
|
||||
static const char *errorCorrectionHelpText = R"(
|
||||
ERROR CORRECTION MODES
|
||||
auto-fast
|
||||
Detects inversion artifacts and distance errors that do not affect edges by range testing.
|
||||
auto-full
|
||||
Detects inversion artifacts and distance errors that do not affect edges by exact distance evaluation.
|
||||
auto-mixed (default)
|
||||
Detects inversions by distance evaluation and distance errors that do not affect edges by range testing.
|
||||
disabled
|
||||
Disables error correction.
|
||||
distance-fast
|
||||
Detects distance errors by range testing. Does not care if edges and corners are affected.
|
||||
distance-full
|
||||
Detects distance errors by exact distance evaluation. Does not care if edges and corners are affected, slow.
|
||||
edge-fast
|
||||
Detects inversion artifacts only by range testing.
|
||||
edge-full
|
||||
Detects inversion artifacts only by exact distance evaluation.
|
||||
help
|
||||
Displays this help.
|
||||
)";
|
||||
|
||||
static char toupper(char c) {
|
||||
return c >= 'a' && c <= 'z' ? c-'a'+'A' : c;
|
||||
}
|
||||
|
||||
static bool parseUnsigned(unsigned &value, const char *arg) {
|
||||
static char c;
|
||||
return sscanf(arg, "%u%c", &value, &c) == 1;
|
||||
}
|
||||
|
||||
static bool parseUnsignedLL(unsigned long long &value, const char *arg) {
|
||||
static char c;
|
||||
return sscanf(arg, "%llu%c", &value, &c) == 1;
|
||||
}
|
||||
|
||||
static bool parseDouble(double &value, const char *arg) {
|
||||
static char c;
|
||||
return sscanf(arg, "%lf%c", &value, &c) == 1;
|
||||
}
|
||||
|
||||
static bool parseAngle(double &value, const char *arg) {
|
||||
char c1, c2;
|
||||
int result = sscanf(arg, "%lf%c%c", &value, &c1, &c2);
|
||||
if (result == 1)
|
||||
return true;
|
||||
if (result == 2 && (c1 == 'd' || c1 == 'D')) {
|
||||
value *= M_PI/180;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool cmpExtension(const char *path, const char *ext) {
|
||||
for (const char *a = path+strlen(path)-1, *b = ext+strlen(ext)-1; b >= ext; --a, --b)
|
||||
if (a < path || toupper(*a) != toupper(*b))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct FontInput {
|
||||
const char *fontFilename;
|
||||
GlyphIdentifierType glyphIdentifierType;
|
||||
const char *charsetFilename;
|
||||
double fontScale;
|
||||
const char *fontName;
|
||||
};
|
||||
|
||||
struct Configuration {
|
||||
ImageType imageType;
|
||||
ImageFormat imageFormat;
|
||||
YDirection yDirection;
|
||||
int width, height;
|
||||
double emSize;
|
||||
double pxRange;
|
||||
double angleThreshold;
|
||||
double miterLimit;
|
||||
void (*edgeColoring)(msdfgen::Shape &, double, unsigned long long);
|
||||
bool expensiveColoring;
|
||||
unsigned long long coloringSeed;
|
||||
GeneratorAttributes generatorAttributes;
|
||||
bool preprocessGeometry;
|
||||
bool kerning;
|
||||
int threadCount;
|
||||
const char *arteryFontFilename;
|
||||
const char *imageFilename;
|
||||
const char *jsonFilename;
|
||||
const char *csvFilename;
|
||||
const char *shadronPreviewFilename;
|
||||
const char *shadronPreviewText;
|
||||
};
|
||||
|
||||
template <typename T, typename S, int N, GeneratorFunction<S, N> GEN_FN>
|
||||
static bool makeAtlas(const std::vector<GlyphGeometry> &glyphs, const std::vector<FontGeometry> &fonts, const Configuration &config) {
|
||||
ImmediateAtlasGenerator<S, N, GEN_FN, BitmapAtlasStorage<T, N> > generator(config.width, config.height);
|
||||
generator.setAttributes(config.generatorAttributes);
|
||||
generator.setThreadCount(config.threadCount);
|
||||
generator.generate(glyphs.data(), glyphs.size());
|
||||
msdfgen::BitmapConstRef<T, N> bitmap = (msdfgen::BitmapConstRef<T, N>) generator.atlasStorage();
|
||||
|
||||
bool success = true;
|
||||
|
||||
if (config.imageFilename) {
|
||||
if (saveImage(bitmap, config.imageFormat, config.imageFilename, config.yDirection))
|
||||
puts("Atlas image file saved.");
|
||||
else {
|
||||
success = false;
|
||||
puts("Failed to save the atlas as an image file.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.arteryFontFilename) {
|
||||
ArteryFontExportProperties arfontProps;
|
||||
arfontProps.fontSize = config.emSize;
|
||||
arfontProps.pxRange = config.pxRange;
|
||||
arfontProps.imageType = config.imageType;
|
||||
arfontProps.imageFormat = config.imageFormat;
|
||||
arfontProps.yDirection = config.yDirection;
|
||||
if (exportArteryFont<float>(fonts.data(), fonts.size(), bitmap, config.arteryFontFilename, arfontProps))
|
||||
puts("Artery Font file generated.");
|
||||
else {
|
||||
success = false;
|
||||
puts("Failed to generate Artery Font file.");
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
int main(int argc, const char * const *argv) {
|
||||
#define ABORT(msg) { puts(msg); return 1; }
|
||||
|
||||
int result = 0;
|
||||
std::vector<FontInput> fontInputs;
|
||||
FontInput fontInput = { };
|
||||
Configuration config = { };
|
||||
fontInput.glyphIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
||||
fontInput.fontScale = -1;
|
||||
config.imageType = ImageType::MSDF;
|
||||
config.imageFormat = ImageFormat::UNSPECIFIED;
|
||||
config.yDirection = YDirection::BOTTOM_UP;
|
||||
config.edgeColoring = msdfgen::edgeColoringInkTrap;
|
||||
config.kerning = true;
|
||||
const char *imageFormatName = nullptr;
|
||||
int fixedWidth = -1, fixedHeight = -1;
|
||||
config.preprocessGeometry = (
|
||||
#ifdef MSDFGEN_USE_SKIA
|
||||
true
|
||||
#else
|
||||
false
|
||||
#endif
|
||||
);
|
||||
config.generatorAttributes.config.overlapSupport = !config.preprocessGeometry;
|
||||
config.generatorAttributes.scanlinePass = !config.preprocessGeometry;
|
||||
double minEmSize = 0;
|
||||
enum {
|
||||
/// Range specified in EMs
|
||||
RANGE_EM,
|
||||
/// Range specified in output pixels
|
||||
RANGE_PIXEL,
|
||||
} rangeMode = RANGE_PIXEL;
|
||||
double rangeValue = 0;
|
||||
TightAtlasPacker::DimensionsConstraint atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE;
|
||||
config.angleThreshold = DEFAULT_ANGLE_THRESHOLD;
|
||||
config.miterLimit = DEFAULT_MITER_LIMIT;
|
||||
config.threadCount = 0;
|
||||
|
||||
// Parse command line
|
||||
int argPos = 1;
|
||||
bool suggestHelp = false;
|
||||
bool explicitErrorCorrectionMode = false;
|
||||
while (argPos < argc) {
|
||||
const char *arg = argv[argPos];
|
||||
#define ARG_CASE(s, p) if (!strcmp(arg, s) && argPos+(p) < argc)
|
||||
|
||||
ARG_CASE("-type", 1) {
|
||||
arg = argv[++argPos];
|
||||
if (!strcmp(arg, "hardmask"))
|
||||
config.imageType = ImageType::HARD_MASK;
|
||||
else if (!strcmp(arg, "softmask"))
|
||||
config.imageType = ImageType::SOFT_MASK;
|
||||
else if (!strcmp(arg, "sdf"))
|
||||
config.imageType = ImageType::SDF;
|
||||
else if (!strcmp(arg, "psdf"))
|
||||
config.imageType = ImageType::PSDF;
|
||||
else if (!strcmp(arg, "msdf"))
|
||||
config.imageType = ImageType::MSDF;
|
||||
else if (!strcmp(arg, "mtsdf"))
|
||||
config.imageType = ImageType::MTSDF;
|
||||
else
|
||||
ABORT("Invalid atlas type. Valid types are: hardmask, softmask, sdf, psdf, msdf, mtsdf");
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-format", 1) {
|
||||
arg = argv[++argPos];
|
||||
if (!strcmp(arg, "png"))
|
||||
config.imageFormat = ImageFormat::PNG;
|
||||
else if (!strcmp(arg, "bmp"))
|
||||
config.imageFormat = ImageFormat::BMP;
|
||||
else if (!strcmp(arg, "tiff"))
|
||||
config.imageFormat = ImageFormat::TIFF;
|
||||
else if (!strcmp(arg, "text"))
|
||||
config.imageFormat = ImageFormat::TEXT;
|
||||
else if (!strcmp(arg, "textfloat"))
|
||||
config.imageFormat = ImageFormat::TEXT_FLOAT;
|
||||
else if (!strcmp(arg, "bin"))
|
||||
config.imageFormat = ImageFormat::BINARY;
|
||||
else if (!strcmp(arg, "binfloat"))
|
||||
config.imageFormat = ImageFormat::BINARY_FLOAT;
|
||||
else if (!strcmp(arg, "binfloatbe"))
|
||||
config.imageFormat = ImageFormat::BINARY_FLOAT_BE;
|
||||
else
|
||||
ABORT("Invalid image format. Valid formats are: png, bmp, tiff, text, textfloat, bin, binfloat");
|
||||
imageFormatName = arg;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-font", 1) {
|
||||
fontInput.fontFilename = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-charset", 1) {
|
||||
fontInput.charsetFilename = argv[++argPos];
|
||||
fontInput.glyphIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-glyphset", 1) {
|
||||
fontInput.charsetFilename = argv[++argPos];
|
||||
fontInput.glyphIdentifierType = GlyphIdentifierType::GLYPH_INDEX;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-fontscale", 1) {
|
||||
double fs;
|
||||
if (!(parseDouble(fs, argv[++argPos]) && fs > 0))
|
||||
ABORT("Invalid font scale argument. Use -fontscale <font scale> with a positive real number.");
|
||||
fontInput.fontScale = fs;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-fontname", 1) {
|
||||
fontInput.fontName = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-and", 0) {
|
||||
if (!fontInput.fontFilename && !fontInput.charsetFilename && fontInput.fontScale < 0)
|
||||
ABORT("No font, character set, or font scale specified before -and separator.");
|
||||
if (!fontInputs.empty() && !memcmp(&fontInputs.back(), &fontInput, sizeof(FontInput)))
|
||||
ABORT("No changes between subsequent inputs. A different font, character set, or font scale must be set inbetween -and separators.");
|
||||
fontInputs.push_back(fontInput);
|
||||
fontInput.fontName = nullptr;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-arfont", 1) {
|
||||
config.arteryFontFilename = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-imageout", 1) {
|
||||
config.imageFilename = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-json", 1) {
|
||||
config.jsonFilename = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-csv", 1) {
|
||||
config.csvFilename = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-shadronpreview", 2) {
|
||||
config.shadronPreviewFilename = argv[++argPos];
|
||||
config.shadronPreviewText = argv[++argPos];
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-dimensions", 2) {
|
||||
unsigned w, h;
|
||||
if (!(parseUnsigned(w, argv[argPos+1]) && parseUnsigned(h, argv[argPos+2]) && w && h))
|
||||
ABORT("Invalid atlas dimensions. Use -dimensions <width> <height> with two positive integers.");
|
||||
fixedWidth = w, fixedHeight = h;
|
||||
argPos += 3;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-pots", 0) {
|
||||
atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::POWER_OF_TWO_SQUARE;
|
||||
fixedWidth = -1, fixedHeight = -1;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-potr", 0) {
|
||||
atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::POWER_OF_TWO_RECTANGLE;
|
||||
fixedWidth = -1, fixedHeight = -1;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-square", 0) {
|
||||
atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::SQUARE;
|
||||
fixedWidth = -1, fixedHeight = -1;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-square2", 0) {
|
||||
atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::EVEN_SQUARE;
|
||||
fixedWidth = -1, fixedHeight = -1;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-square4", 0) {
|
||||
atlasSizeConstraint = TightAtlasPacker::DimensionsConstraint::MULTIPLE_OF_FOUR_SQUARE;
|
||||
fixedWidth = -1, fixedHeight = -1;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-yorigin", 1) {
|
||||
arg = argv[++argPos];
|
||||
if (!strcmp(arg, "bottom"))
|
||||
config.yDirection = YDirection::BOTTOM_UP;
|
||||
else if (!strcmp(arg, "top"))
|
||||
config.yDirection = YDirection::TOP_DOWN;
|
||||
else
|
||||
ABORT("Invalid Y-axis origin. Use bottom or top.");
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-size", 1) {
|
||||
double s;
|
||||
if (!(parseDouble(s, argv[++argPos]) && s > 0))
|
||||
ABORT("Invalid EM size argument. Use -size <EM size> with a positive real number.");
|
||||
config.emSize = s;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-minsize", 1) {
|
||||
double s;
|
||||
if (!(parseDouble(s, argv[++argPos]) && s > 0))
|
||||
ABORT("Invalid minimum EM size argument. Use -minsize <EM size> with a positive real number.");
|
||||
minEmSize = s;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-emrange", 1) {
|
||||
double r;
|
||||
if (!(parseDouble(r, argv[++argPos]) && r >= 0))
|
||||
ABORT("Invalid range argument. Use -emrange <EM range> with a positive real number.");
|
||||
rangeMode = RANGE_EM;
|
||||
rangeValue = r;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-pxrange", 1) {
|
||||
double r;
|
||||
if (!(parseDouble(r, argv[++argPos]) && r >= 0))
|
||||
ABORT("Invalid range argument. Use -pxrange <pixel range> with a positive real number.");
|
||||
rangeMode = RANGE_PIXEL;
|
||||
rangeValue = r;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-angle", 1) {
|
||||
double at;
|
||||
if (!parseAngle(at, argv[argPos+1]))
|
||||
ABORT("Invalid angle threshold. Use -angle <min angle> with a positive real number less than PI or a value in degrees followed by 'd' below 180d.");
|
||||
config.angleThreshold = at;
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-errorcorrection", 1) {
|
||||
msdfgen::ErrorCorrectionConfig &ec = config.generatorAttributes.config.errorCorrection;
|
||||
if (!strcmp(argv[argPos+1], "disabled") || !strcmp(argv[argPos+1], "0") || !strcmp(argv[argPos+1], "none")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::DISABLED;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "default") || !strcmp(argv[argPos+1], "auto") || !strcmp(argv[argPos+1], "auto-mixed") || !strcmp(argv[argPos+1], "mixed")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::EDGE_PRIORITY;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::CHECK_DISTANCE_AT_EDGE;
|
||||
} else if (!strcmp(argv[argPos+1], "auto-fast") || !strcmp(argv[argPos+1], "fast")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::EDGE_PRIORITY;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "auto-full") || !strcmp(argv[argPos+1], "full")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::EDGE_PRIORITY;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::ALWAYS_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "distance") || !strcmp(argv[argPos+1], "distance-fast") || !strcmp(argv[argPos+1], "indiscriminate") || !strcmp(argv[argPos+1], "indiscriminate-fast")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::INDISCRIMINATE;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "distance-full") || !strcmp(argv[argPos+1], "indiscriminate-full")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::INDISCRIMINATE;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::ALWAYS_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "edge-fast")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::EDGE_ONLY;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "edge") || !strcmp(argv[argPos+1], "edge-full")) {
|
||||
ec.mode = msdfgen::ErrorCorrectionConfig::EDGE_ONLY;
|
||||
ec.distanceCheckMode = msdfgen::ErrorCorrectionConfig::ALWAYS_CHECK_DISTANCE;
|
||||
} else if (!strcmp(argv[argPos+1], "help")) {
|
||||
puts(errorCorrectionHelpText);
|
||||
return 0;
|
||||
} else
|
||||
ABORT("Unknown error correction mode. Use -errorcorrection help for more information.");
|
||||
explicitErrorCorrectionMode = true;
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-errordeviationratio", 1) {
|
||||
double edr;
|
||||
if (!(parseDouble(edr, argv[argPos+1]) && edr > 0))
|
||||
ABORT("Invalid error deviation ratio. Use -errordeviationratio <ratio> with a positive real number.");
|
||||
config.generatorAttributes.config.errorCorrection.minDeviationRatio = edr;
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-errorimproveratio", 1) {
|
||||
double eir;
|
||||
if (!(parseDouble(eir, argv[argPos+1]) && eir > 0))
|
||||
ABORT("Invalid error improvement ratio. Use -errorimproveratio <ratio> with a positive real number.");
|
||||
config.generatorAttributes.config.errorCorrection.minImproveRatio = eir;
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-coloringstrategy", 1) {
|
||||
if (!strcmp(argv[argPos+1], "simple")) config.edgeColoring = msdfgen::edgeColoringSimple, config.expensiveColoring = false;
|
||||
else if (!strcmp(argv[argPos+1], "inktrap")) config.edgeColoring = msdfgen::edgeColoringInkTrap, config.expensiveColoring = false;
|
||||
else if (!strcmp(argv[argPos+1], "distance")) config.edgeColoring = msdfgen::edgeColoringByDistance, config.expensiveColoring = true;
|
||||
else
|
||||
puts("Unknown coloring strategy specified.");
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-miterlimit", 1) {
|
||||
double m;
|
||||
if (!(parseDouble(m, argv[++argPos]) && m >= 0))
|
||||
ABORT("Invalid miter limit argument. Use -miterlimit <limit> with a positive real number.");
|
||||
config.miterLimit = m;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-nokerning", 0) {
|
||||
config.kerning = false;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-kerning", 0) {
|
||||
config.kerning = true;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-nopreprocess", 0) {
|
||||
config.preprocessGeometry = false;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-preprocess", 0) {
|
||||
config.preprocessGeometry = true;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-nooverlap", 0) {
|
||||
config.generatorAttributes.config.overlapSupport = false;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-overlap", 0) {
|
||||
config.generatorAttributes.config.overlapSupport = true;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-noscanline", 0) {
|
||||
config.generatorAttributes.scanlinePass = false;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-scanline", 0) {
|
||||
config.generatorAttributes.scanlinePass = true;
|
||||
++argPos;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-seed", 1) {
|
||||
if (!parseUnsignedLL(config.coloringSeed, argv[argPos+1]))
|
||||
ABORT("Invalid seed. Use -seed <N> with N being a non-negative integer.");
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-threads", 1) {
|
||||
unsigned tc;
|
||||
if (!parseUnsigned(tc, argv[argPos+1]) || (int) tc < 0)
|
||||
ABORT("Invalid thread count. Use -threads <N> with N being a non-negative integer.");
|
||||
config.threadCount = (int) tc;
|
||||
argPos += 2;
|
||||
continue;
|
||||
}
|
||||
ARG_CASE("-help", 0) {
|
||||
puts(helpText);
|
||||
return 0;
|
||||
}
|
||||
printf("Unknown setting or insufficient parameters: %s\n", arg);
|
||||
suggestHelp = true;
|
||||
++argPos;
|
||||
}
|
||||
if (suggestHelp)
|
||||
printf("Use -help for more information.\n");
|
||||
|
||||
// Nothing to do?
|
||||
if (argc == 1) {
|
||||
printf(
|
||||
"Usage: msdf-atlas-gen"
|
||||
#ifdef _WIN32
|
||||
".exe"
|
||||
#endif
|
||||
" -font <filename.ttf/otf> -charset <charset> <output specification> <options>\n"
|
||||
"Use -help for more information.\n"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
if (!fontInput.fontFilename)
|
||||
ABORT("No font specified.");
|
||||
if (!(config.arteryFontFilename || config.imageFilename || config.jsonFilename || config.csvFilename || config.shadronPreviewFilename)) {
|
||||
puts("No output specified.");
|
||||
return 0;
|
||||
}
|
||||
bool layoutOnly = !(config.arteryFontFilename || config.imageFilename);
|
||||
|
||||
// Finalize font inputs
|
||||
const FontInput *nextFontInput = &fontInput;
|
||||
for (std::vector<FontInput>::reverse_iterator it = fontInputs.rbegin(); it != fontInputs.rend(); ++it) {
|
||||
if (!it->fontFilename && nextFontInput->fontFilename)
|
||||
it->fontFilename = nextFontInput->fontFilename;
|
||||
if (!it->charsetFilename && nextFontInput->charsetFilename) {
|
||||
it->charsetFilename = nextFontInput->charsetFilename;
|
||||
it->glyphIdentifierType = nextFontInput->glyphIdentifierType;
|
||||
}
|
||||
if (it->fontScale < 0 && nextFontInput->fontScale >= 0)
|
||||
it->fontScale = nextFontInput->fontScale;
|
||||
nextFontInput = &*it;
|
||||
}
|
||||
if (fontInputs.empty() || memcmp(&fontInputs.back(), &fontInput, sizeof(FontInput)))
|
||||
fontInputs.push_back(fontInput);
|
||||
|
||||
// Fix up configuration based on related values
|
||||
if (!(config.imageType == ImageType::PSDF || config.imageType == ImageType::MSDF || config.imageType == ImageType::MTSDF))
|
||||
config.miterLimit = 0;
|
||||
if (config.emSize > minEmSize)
|
||||
minEmSize = config.emSize;
|
||||
if (!(fixedWidth > 0 && fixedHeight > 0) && !(minEmSize > 0)) {
|
||||
puts("Neither atlas size nor glyph size selected, using default...");
|
||||
minEmSize = MSDF_ATLAS_DEFAULT_EM_SIZE;
|
||||
}
|
||||
if (!(config.imageType == ImageType::SDF || config.imageType == ImageType::PSDF || config.imageType == ImageType::MSDF || config.imageType == ImageType::MTSDF)) {
|
||||
rangeMode = RANGE_PIXEL;
|
||||
rangeValue = (double) (config.imageType == ImageType::SOFT_MASK);
|
||||
} else if (rangeValue <= 0) {
|
||||
rangeMode = RANGE_PIXEL;
|
||||
rangeValue = DEFAULT_PIXEL_RANGE;
|
||||
}
|
||||
if (config.kerning && !(config.arteryFontFilename || config.jsonFilename || config.shadronPreviewFilename))
|
||||
config.kerning = false;
|
||||
if (config.threadCount <= 0)
|
||||
config.threadCount = std::max((int) std::thread::hardware_concurrency(), 1);
|
||||
if (config.generatorAttributes.scanlinePass) {
|
||||
if (explicitErrorCorrectionMode && config.generatorAttributes.config.errorCorrection.distanceCheckMode != msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE) {
|
||||
const char *fallbackModeName = "unknown";
|
||||
switch (config.generatorAttributes.config.errorCorrection.mode) {
|
||||
case msdfgen::ErrorCorrectionConfig::DISABLED: fallbackModeName = "disabled"; break;
|
||||
case msdfgen::ErrorCorrectionConfig::INDISCRIMINATE: fallbackModeName = "distance-fast"; break;
|
||||
case msdfgen::ErrorCorrectionConfig::EDGE_PRIORITY: fallbackModeName = "auto-fast"; break;
|
||||
case msdfgen::ErrorCorrectionConfig::EDGE_ONLY: fallbackModeName = "edge-fast"; break;
|
||||
}
|
||||
printf("Selected error correction mode not compatible with scanline mode, falling back to %s.\n", fallbackModeName);
|
||||
}
|
||||
config.generatorAttributes.config.errorCorrection.distanceCheckMode = msdfgen::ErrorCorrectionConfig::DO_NOT_CHECK_DISTANCE;
|
||||
}
|
||||
|
||||
// Finalize image format
|
||||
ImageFormat imageExtension = ImageFormat::UNSPECIFIED;
|
||||
if (config.imageFilename) {
|
||||
if (cmpExtension(config.imageFilename, ".png")) imageExtension = ImageFormat::PNG;
|
||||
else if (cmpExtension(config.imageFilename, ".bmp")) imageExtension = ImageFormat::BMP;
|
||||
else if (cmpExtension(config.imageFilename, ".tif") || cmpExtension(config.imageFilename, ".tiff")) imageExtension = ImageFormat::TIFF;
|
||||
else if (cmpExtension(config.imageFilename, ".txt")) imageExtension = ImageFormat::TEXT;
|
||||
else if (cmpExtension(config.imageFilename, ".bin")) imageExtension = ImageFormat::BINARY;
|
||||
}
|
||||
if (config.imageFormat == ImageFormat::UNSPECIFIED) {
|
||||
config.imageFormat = ImageFormat::PNG;
|
||||
imageFormatName = "png";
|
||||
// If image format is not specified and -imageout is the only image output, infer format from its extension
|
||||
if (imageExtension != ImageFormat::UNSPECIFIED && !config.arteryFontFilename)
|
||||
config.imageFormat = imageExtension;
|
||||
}
|
||||
if (config.imageType == ImageType::MTSDF && config.imageFormat == ImageFormat::BMP)
|
||||
ABORT("Atlas type not compatible with image format. MTSDF requires a format with alpha channel.");
|
||||
if (config.arteryFontFilename && !(config.imageFormat == ImageFormat::PNG || config.imageFormat == ImageFormat::BINARY || config.imageFormat == ImageFormat::BINARY_FLOAT)) {
|
||||
config.arteryFontFilename = nullptr;
|
||||
result = 1;
|
||||
puts("Error: Unable to create an Artery Font file with the specified image format!");
|
||||
// Recheck whether there is anything else to do
|
||||
if (!(config.arteryFontFilename || config.imageFilename || config.jsonFilename || config.csvFilename || config.shadronPreviewFilename))
|
||||
return result;
|
||||
layoutOnly = !(config.arteryFontFilename || config.imageFilename);
|
||||
}
|
||||
if (imageExtension != ImageFormat::UNSPECIFIED) {
|
||||
// Warn if image format mismatches -imageout extension
|
||||
bool mismatch = false;
|
||||
switch (config.imageFormat) {
|
||||
case ImageFormat::TEXT: case ImageFormat::TEXT_FLOAT:
|
||||
mismatch = imageExtension != ImageFormat::TEXT;
|
||||
break;
|
||||
case ImageFormat::BINARY: case ImageFormat::BINARY_FLOAT: case ImageFormat::BINARY_FLOAT_BE:
|
||||
mismatch = imageExtension != ImageFormat::BINARY;
|
||||
break;
|
||||
default:
|
||||
mismatch = imageExtension != config.imageFormat;
|
||||
}
|
||||
if (mismatch)
|
||||
printf("Warning: Output image file extension does not match the image's actual format (%s)!\n", imageFormatName);
|
||||
}
|
||||
imageFormatName = nullptr; // No longer consistent with imageFormat
|
||||
bool floatingPointFormat = (
|
||||
config.imageFormat == ImageFormat::TIFF ||
|
||||
config.imageFormat == ImageFormat::TEXT_FLOAT ||
|
||||
config.imageFormat == ImageFormat::BINARY_FLOAT ||
|
||||
config.imageFormat == ImageFormat::BINARY_FLOAT_BE
|
||||
);
|
||||
|
||||
// Load fonts
|
||||
std::vector<GlyphGeometry> glyphs;
|
||||
std::vector<FontGeometry> fonts;
|
||||
bool anyCodepointsAvailable = false;
|
||||
{
|
||||
class FontHolder {
|
||||
msdfgen::FreetypeHandle *ft;
|
||||
msdfgen::FontHandle *font;
|
||||
const char *fontFilename;
|
||||
public:
|
||||
FontHolder() : ft(msdfgen::initializeFreetype()), font(nullptr), fontFilename(nullptr) { }
|
||||
~FontHolder() {
|
||||
if (ft) {
|
||||
if (font)
|
||||
msdfgen::destroyFont(font);
|
||||
msdfgen::deinitializeFreetype(ft);
|
||||
}
|
||||
}
|
||||
bool load(const char *fontFilename) {
|
||||
if (ft && fontFilename) {
|
||||
if (this->fontFilename && !strcmp(this->fontFilename, fontFilename))
|
||||
return true;
|
||||
if (font)
|
||||
msdfgen::destroyFont(font);
|
||||
if ((font = msdfgen::loadFont(ft, fontFilename))) {
|
||||
this->fontFilename = fontFilename;
|
||||
return true;
|
||||
}
|
||||
this->fontFilename = nullptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
operator msdfgen::FontHandle *() const {
|
||||
return font;
|
||||
}
|
||||
} font;
|
||||
|
||||
for (FontInput &fontInput : fontInputs) {
|
||||
if (!font.load(fontInput.fontFilename))
|
||||
ABORT("Failed to load specified font file.");
|
||||
if (fontInput.fontScale <= 0)
|
||||
fontInput.fontScale = 1;
|
||||
|
||||
// Load character set
|
||||
Charset charset;
|
||||
if (fontInput.charsetFilename) {
|
||||
if (!charset.load(fontInput.charsetFilename, fontInput.glyphIdentifierType != GlyphIdentifierType::UNICODE_CODEPOINT))
|
||||
ABORT(fontInput.glyphIdentifierType == GlyphIdentifierType::GLYPH_INDEX ? "Failed to load glyph set specification." : "Failed to load character set specification.");
|
||||
} else {
|
||||
charset = Charset::ASCII;
|
||||
fontInput.glyphIdentifierType = GlyphIdentifierType::UNICODE_CODEPOINT;
|
||||
}
|
||||
|
||||
// Load glyphs
|
||||
FontGeometry fontGeometry(&glyphs);
|
||||
int glyphsLoaded = -1;
|
||||
switch (fontInput.glyphIdentifierType) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
glyphsLoaded = fontGeometry.loadGlyphset(font, fontInput.fontScale, charset, config.preprocessGeometry, config.kerning);
|
||||
break;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
glyphsLoaded = fontGeometry.loadCharset(font, fontInput.fontScale, charset, config.preprocessGeometry, config.kerning);
|
||||
anyCodepointsAvailable |= glyphsLoaded > 0;
|
||||
break;
|
||||
}
|
||||
if (glyphsLoaded < 0)
|
||||
ABORT("Failed to load glyphs from font.");
|
||||
printf("Loaded geometry of %d out of %d glyphs", glyphsLoaded, (int) charset.size());
|
||||
if (fontInputs.size() > 1)
|
||||
printf(" from font \"%s\"", fontInput.fontFilename);
|
||||
printf(".\n");
|
||||
// List missing glyphs
|
||||
if (glyphsLoaded < (int) charset.size()) {
|
||||
printf("Missing %d %s", (int) charset.size()-glyphsLoaded, fontInput.glyphIdentifierType == GlyphIdentifierType::UNICODE_CODEPOINT ? "codepoints" : "glyphs");
|
||||
bool first = true;
|
||||
switch (fontInput.glyphIdentifierType) {
|
||||
case GlyphIdentifierType::GLYPH_INDEX:
|
||||
for (unicode_t cp : charset)
|
||||
if (!fontGeometry.getGlyph(msdfgen::GlyphIndex(cp)))
|
||||
printf("%c 0x%02X", first ? ((first = false), ':') : ',', cp);
|
||||
break;
|
||||
case GlyphIdentifierType::UNICODE_CODEPOINT:
|
||||
for (unicode_t cp : charset)
|
||||
if (!fontGeometry.getGlyph(cp))
|
||||
printf("%c 0x%02X", first ? ((first = false), ':') : ',', cp);
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (fontInput.fontName)
|
||||
fontGeometry.setName(fontInput.fontName);
|
||||
|
||||
fonts.push_back((FontGeometry &&) fontGeometry);
|
||||
}
|
||||
}
|
||||
if (glyphs.empty())
|
||||
ABORT("No glyphs loaded.");
|
||||
|
||||
// Determine final atlas dimensions, scale and range, pack glyphs
|
||||
{
|
||||
double unitRange = 0, pxRange = 0;
|
||||
switch (rangeMode) {
|
||||
case RANGE_EM:
|
||||
unitRange = rangeValue;
|
||||
break;
|
||||
case RANGE_PIXEL:
|
||||
pxRange = rangeValue;
|
||||
break;
|
||||
}
|
||||
bool fixedDimensions = fixedWidth >= 0 && fixedHeight >= 0;
|
||||
bool fixedScale = config.emSize > 0;
|
||||
TightAtlasPacker atlasPacker;
|
||||
if (fixedDimensions)
|
||||
atlasPacker.setDimensions(fixedWidth, fixedHeight);
|
||||
else
|
||||
atlasPacker.setDimensionsConstraint(atlasSizeConstraint);
|
||||
atlasPacker.setPadding(config.imageType == ImageType::MSDF || config.imageType == ImageType::MTSDF ? 0 : -1);
|
||||
// TODO: In this case (if padding is -1), the border pixels of each glyph are black, but still computed. For floating-point output, this may play a role.
|
||||
if (fixedScale)
|
||||
atlasPacker.setScale(config.emSize);
|
||||
else
|
||||
atlasPacker.setMinimumScale(minEmSize);
|
||||
atlasPacker.setPixelRange(pxRange);
|
||||
atlasPacker.setUnitRange(unitRange);
|
||||
atlasPacker.setMiterLimit(config.miterLimit);
|
||||
if (int remaining = atlasPacker.pack(glyphs.data(), glyphs.size())) {
|
||||
if (remaining < 0) {
|
||||
ABORT("Failed to pack glyphs into atlas.");
|
||||
} else {
|
||||
printf("Error: Could not fit %d out of %d glyphs into the atlas.\n", remaining, (int) glyphs.size());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
atlasPacker.getDimensions(config.width, config.height);
|
||||
if (!(config.width > 0 && config.height > 0))
|
||||
ABORT("Unable to determine atlas size.");
|
||||
config.emSize = atlasPacker.getScale();
|
||||
config.pxRange = atlasPacker.getPixelRange();
|
||||
if (!fixedScale)
|
||||
printf("Glyph size: %.9g pixels/EM\n", config.emSize);
|
||||
if (!fixedDimensions)
|
||||
printf("Atlas dimensions: %d x %d\n", config.width, config.height);
|
||||
}
|
||||
|
||||
// Generate atlas bitmap
|
||||
if (!layoutOnly) {
|
||||
|
||||
// Edge coloring
|
||||
if (config.imageType == ImageType::MSDF || config.imageType == ImageType::MTSDF) {
|
||||
if (config.expensiveColoring) {
|
||||
Workload([&glyphs, &config](int i, int threadNo) -> bool {
|
||||
unsigned long long glyphSeed = (LCG_MULTIPLIER*(config.coloringSeed^i)+LCG_INCREMENT)*!!config.coloringSeed;
|
||||
glyphs[i].edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed);
|
||||
return true;
|
||||
}, glyphs.size()).finish(config.threadCount);
|
||||
} else {
|
||||
unsigned long long glyphSeed = config.coloringSeed;
|
||||
for (GlyphGeometry &glyph : glyphs) {
|
||||
glyphSeed *= LCG_MULTIPLIER;
|
||||
glyph.edgeColoring(config.edgeColoring, config.angleThreshold, glyphSeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (config.imageType) {
|
||||
case ImageType::HARD_MASK:
|
||||
if (floatingPointFormat)
|
||||
success = makeAtlas<float, float, 1, scanlineGenerator>(glyphs, fonts, config);
|
||||
else
|
||||
success = makeAtlas<byte, float, 1, scanlineGenerator>(glyphs, fonts, config);
|
||||
break;
|
||||
case ImageType::SOFT_MASK:
|
||||
case ImageType::SDF:
|
||||
if (floatingPointFormat)
|
||||
success = makeAtlas<float, float, 1, sdfGenerator>(glyphs, fonts, config);
|
||||
else
|
||||
success = makeAtlas<byte, float, 1, sdfGenerator>(glyphs, fonts, config);
|
||||
break;
|
||||
case ImageType::PSDF:
|
||||
if (floatingPointFormat)
|
||||
success = makeAtlas<float, float, 1, psdfGenerator>(glyphs, fonts, config);
|
||||
else
|
||||
success = makeAtlas<byte, float, 1, psdfGenerator>(glyphs, fonts, config);
|
||||
break;
|
||||
case ImageType::MSDF:
|
||||
if (floatingPointFormat)
|
||||
success = makeAtlas<float, float, 3, msdfGenerator>(glyphs, fonts, config);
|
||||
else
|
||||
success = makeAtlas<byte, float, 3, msdfGenerator>(glyphs, fonts, config);
|
||||
break;
|
||||
case ImageType::MTSDF:
|
||||
if (floatingPointFormat)
|
||||
success = makeAtlas<float, float, 4, mtsdfGenerator>(glyphs, fonts, config);
|
||||
else
|
||||
success = makeAtlas<byte, float, 4, mtsdfGenerator>(glyphs, fonts, config);
|
||||
break;
|
||||
}
|
||||
if (!success)
|
||||
result = 1;
|
||||
}
|
||||
|
||||
if (config.csvFilename) {
|
||||
if (exportCSV(fonts.data(), fonts.size(), config.width, config.height, config.yDirection, config.csvFilename))
|
||||
puts("Glyph layout written into CSV file.");
|
||||
else {
|
||||
result = 1;
|
||||
puts("Failed to write CSV output file.");
|
||||
}
|
||||
}
|
||||
if (config.jsonFilename) {
|
||||
if (exportJSON(fonts.data(), fonts.size(), config.emSize, config.pxRange, config.width, config.height, config.imageType, config.yDirection, config.jsonFilename, config.kerning))
|
||||
puts("Glyph layout and metadata written into JSON file.");
|
||||
else {
|
||||
result = 1;
|
||||
puts("Failed to write JSON output file.");
|
||||
}
|
||||
}
|
||||
|
||||
if (config.shadronPreviewFilename && config.shadronPreviewText) {
|
||||
if (anyCodepointsAvailable) {
|
||||
std::vector<unicode_t> previewText;
|
||||
utf8Decode(previewText, config.shadronPreviewText);
|
||||
previewText.push_back(0);
|
||||
if (generateShadronPreview(fonts.data(), fonts.size(), config.imageType, config.width, config.height, config.pxRange, previewText.data(), config.imageFilename, floatingPointFormat, config.shadronPreviewFilename))
|
||||
puts("Shadron preview script generated.");
|
||||
else {
|
||||
result = 1;
|
||||
puts("Failed to generate Shadron preview file.");
|
||||
}
|
||||
} else {
|
||||
result = 1;
|
||||
puts("Shadron preview not supported in -glyphset mode.");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
42
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.h
Normal file
42
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.h
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* MULTI-CHANNEL SIGNED DISTANCE FIELD ATLAS GENERATOR v1.2 (2021-05-29)
|
||||
* ---------------------------------------------------------------------
|
||||
* A utility by Viktor Chlumsky, (c) 2020 - 2021
|
||||
*
|
||||
* Generates compact bitmap font atlases using MSDFGEN.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <msdfgen.h>
|
||||
#include <msdfgen-ext.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utf8.h"
|
||||
#include "Rectangle.h"
|
||||
#include "Charset.h"
|
||||
#include "GlyphBox.h"
|
||||
#include "GlyphGeometry.h"
|
||||
#include "FontGeometry.h"
|
||||
#include "RectanglePacker.h"
|
||||
#include "rectangle-packing.h"
|
||||
#include "Workload.h"
|
||||
#include "size-selectors.h"
|
||||
#include "bitmap-blit.h"
|
||||
#include "AtlasStorage.h"
|
||||
#include "BitmapAtlasStorage.h"
|
||||
#include "TightAtlasPacker.h"
|
||||
#include "AtlasGenerator.h"
|
||||
#include "ImmediateAtlasGenerator.h"
|
||||
#include "DynamicAtlas.h"
|
||||
#include "glyph-generators.h"
|
||||
#include "image-encode.h"
|
||||
#include "image-save.h"
|
||||
#include "artery-font-export.h"
|
||||
#include "csv-export.h"
|
||||
#include "json-export.h"
|
||||
#include "shadron-preview-generator.h"
|
||||
|
||||
#define MSDF_ATLAS_VERSION "1.2"
|
||||
BIN
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.rc
Normal file
BIN
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.rc
Normal file
Binary file not shown.
61
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.sln
Normal file
61
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.sln
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Msdfgen", "msdfgen\Msdfgen.vcxproj", "{84BE2D91-F071-4151-BE12-61460464C494}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "msdf-atlas-gen", "msdf-atlas-gen.vcxproj", "{223EDB94-5B35-45F2-A584-273DE6E45F6F}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{84BE2D91-F071-4151-BE12-61460464C494} = {84BE2D91-F071-4151-BE12-61460464C494}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug Library|x64 = Debug Library|x64
|
||||
Debug Library|x86 = Debug Library|x86
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release Library|x64 = Release Library|x64
|
||||
Release Library|x86 = Release Library|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug Library|x64.ActiveCfg = Debug Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug Library|x64.Build.0 = Debug Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug Library|x86.ActiveCfg = Debug Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug Library|x86.Build.0 = Debug Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug|x64.ActiveCfg = Debug Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug|x64.Build.0 = Debug Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug|x86.ActiveCfg = Debug Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Debug|x86.Build.0 = Debug Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release Library|x64.ActiveCfg = Release Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release Library|x64.Build.0 = Release Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release Library|x86.ActiveCfg = Release Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release Library|x86.Build.0 = Release Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release|x64.ActiveCfg = Release Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release|x64.Build.0 = Release Library|x64
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release|x86.ActiveCfg = Release Library|Win32
|
||||
{84BE2D91-F071-4151-BE12-61460464C494}.Release|x86.Build.0 = Release Library|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug Library|x64.ActiveCfg = Debug Library|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug Library|x64.Build.0 = Debug Library|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug Library|x86.ActiveCfg = Debug Library|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug Library|x86.Build.0 = Debug Library|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug|x64.Build.0 = Debug|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Debug|x86.Build.0 = Debug|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release Library|x64.ActiveCfg = Release Library|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release Library|x64.Build.0 = Release Library|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release Library|x86.ActiveCfg = Release Library|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release Library|x86.Build.0 = Release Library|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release|x64.ActiveCfg = Release|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release|x64.Build.0 = Release|x64
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release|x86.ActiveCfg = Release|Win32
|
||||
{223EDB94-5B35-45F2-A584-273DE6E45F6F}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
374
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.vcxproj
Normal file
374
Nuake/src/Vendors/msdf-atlas-gen/msdf-atlas-gen.vcxproj
Normal file
@@ -0,0 +1,374 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug Library|Win32">
|
||||
<Configuration>Debug Library</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug Library|x64">
|
||||
<Configuration>Debug Library</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Library|Win32">
|
||||
<Configuration>Release Library</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release Library|x64">
|
||||
<Configuration>Release Library</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{223EDB94-5B35-45F2-A584-273DE6E45F6F}</ProjectGuid>
|
||||
<RootNamespace>msdfatlasgen</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>bin\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>bin\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'">
|
||||
<TargetName>msdf-atlas-gen</TargetName>
|
||||
<OutDir>$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDF_ATLAS_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;skia.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\$(Configuration);msdfgen\$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\msdfgen\freetype\win32;$(SolutionDir)$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\debug;msdfgen\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDF_ATLAS_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;skia.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\$(Configuration);msdfgen\$(Platform)\$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Library|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\msdfgen\freetype\win64;$(SolutionDir)$(Platform)\$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\debug;msdfgen\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDF_ATLAS_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;skia.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\$(Configuration);msdfgen\bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\msdfgen\freetype\win32;$(SolutionDir)bin;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\release;msdfgen\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;MSDF_ATLAS_STANDALONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;skia.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\$(Configuration);msdfgen\$(Platform)\$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Library|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>msdfgen\include;msdfgen\freetype\include;msdfgen;artery-font-format;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;MSDFGEN_USE_CPP11;MSDFGEN_USE_SKIA;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>freetype.lib;msdfgen.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\msdfgen\freetype\win64;$(SolutionDir)$(Platform)\$(Configuration) Library;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>msdfgen\freetype\win$(PlatformArchitecture);msdfgen\skia\win$(PlatformArchitecture)\release;msdfgen\$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="msdf-atlas-gen\artery-font-export.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\bitmap-blit.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\charset-parser.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\Charset.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\csv-export.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\FontGeometry.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\glyph-generators.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\GlyphGeometry.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\image-encode.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\json-export.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\main.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\RectanglePacker.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\shadron-preview-generator.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\size-selectors.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\TightAtlasPacker.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\utf8.cpp" />
|
||||
<ClCompile Include="msdf-atlas-gen\Workload.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\artery-font-export.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\AtlasGenerator.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\AtlasStorage.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\bitmap-blit.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\BitmapAtlasStorage.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\BitmapAtlasStorage.hpp" />
|
||||
<ClInclude Include="msdf-atlas-gen\csv-export.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\DynamicAtlas.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\DynamicAtlas.hpp" />
|
||||
<ClInclude Include="msdf-atlas-gen\FontGeometry.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\glyph-generators.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\image-encode.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\Charset.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\GlyphGeometry.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\image-save.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\image-save.hpp" />
|
||||
<ClInclude Include="msdf-atlas-gen\ImmediateAtlasGenerator.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\ImmediateAtlasGenerator.hpp" />
|
||||
<ClInclude Include="msdf-atlas-gen\json-export.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\msdf-atlas-gen.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\rectangle-packing.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\rectangle-packing.hpp" />
|
||||
<ClInclude Include="msdf-atlas-gen\Rectangle.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\RectanglePacker.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\Remap.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\shadron-preview-generator.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\size-selectors.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\GlyphBox.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\types.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\utf8.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\Workload.h" />
|
||||
<ClInclude Include="msdf-atlas-gen\TightAtlasPacker.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="msdf-atlas-gen.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="icon.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user