Kaydet (Commit) 73302ce8 authored tarafından Tor Lillqvist's avatar Tor Lillqvist

Exit GLyphy

Change-Id: Ib84e703d4c1528d022435c7695c97a3fc284563a
üst 2a91304b
......@@ -131,7 +131,6 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
$(call fetch_Optional,FREETYPE,FREETYPE_TARBALL) \
$(call fetch_Optional,GLEW,GLEW_TARBALL) \
$(call fetch_Optional,GLM,GLM_TARBALL) \
$(call fetch_Optional,GLYPHY,GLYPHY_TARBALL) \
$(call fetch_Optional_pack,GOOGLE_DOCS_EXTENSION_PACK) \
$(call fetch_Optional,GRAPHITE,GRAPHITE_TARBALL) \
$(call fetch_Optional,HARFBUZZ,HARFBUZZ_TARBALL) \
......
......@@ -229,44 +229,6 @@ endef
endif # SYSTEM_GLEW
ifneq ($(SYSTEM_GLYPHY),)
define gb_LinkTarget__use_glyphy
$(call gb_LinkTarget_set_include,$(1),\
$$(INCLUDE) \
$(GLYPHY_CFLAGS) \
)
$(call gb_LinkTarget_add_libs,$(1),$(GLYPHY_LIBS))
endef
else # !SYSTEM_GLYPHY
$(eval $(call gb_Helper_optional,GLYPHY,$(call gb_Helper_register_packages_for_install,ooo,\
glyphy \
)))
define gb_LinkTarget__use_glyphy
$(call gb_LinkTarget_use_package,$(1),glyphy)
$(call gb_LinkTarget_set_include,$(1),\
-I$(call gb_UnpackedTarball_get_dir,glyphy/src) \
$$(INCLUDE) \
)
ifeq ($(COM),MSC)
$(call gb_LinkTarget_add_libs,$(1),\
$(call gb_UnpackedTarball_get_dir,glyphy)/src/.libs/libglyphy.lib \
)
else
$(call gb_LinkTarget_add_libs,$(1),\
-L$(call gb_UnpackedTarball_get_dir,glyphy)/src/.libs -lglyphy \
)
endif
endef
endif # SYSTEM_GLYPHY
define gb_LinkTarget__use_iconv
$(call gb_LinkTarget_add_libs,$(1),-liconv)
......
......@@ -204,8 +204,6 @@ export GIT_NEEDED_SUBMODULES=@GIT_NEEDED_SUBMODULES@
export GLEW_CFLAGS=$(gb_SPACE)@GLEW_CFLAGS@
export GLEW_LIBS=$(gb_SPACE)@GLEW_LIBS@
export GLM_CFLAGS=$(gb_SPACE)@GLM_CFLAGS@
export GLYPHY_CFLAGS=$(gb_SPACE)@GLYPHY_CFLAGS@
export GLYPHY_LIBS=$(gb_SPACE)@GLYPHY_LIBS@
export GNOMEVFS_CFLAGS=$(gb_SPACE)@GNOMEVFS_CFLAGS@
export GNOMEVFS_LIBS=$(gb_SPACE)@GNOMEVFS_LIBS@
export GNUTLS_CFLAGS=$(gb_SPACE)@GNUTLS_CFLAGS@
......@@ -518,7 +516,6 @@ export SYSTEM_GENCCODE=@SYSTEM_GENCCODE@
export SYSTEM_GENCMN=@SYSTEM_GENCMN@
export SYSTEM_GLEW=@SYSTEM_GLEW@
export SYSTEM_GLM=@SYSTEM_GLM@
export SYSTEM_GLYPHY=@SYSTEM_GLYPHY@
export SYSTEM_GRAPHITE=@SYSTEM_GRAPHITE@
export SYSTEM_HARFBUZZ=@SYSTEM_HARFBUZZ@
export SYSTEM_HSQLDB=@SYSTEM_HSQLDB@
......
......@@ -8948,14 +8948,6 @@ AS_IF([test "$with_system_glew" = "yes"],
[PKG_CHECK_EXISTS([glew >= 1.12.0], [AC_DEFINE([HAVE_GLEW_1_12])])],
[AC_DEFINE([HAVE_GLEW_1_12])])
dnl ===================================================================
dnl Check for system glyphy
dnl ===================================================================
dnl We currently use GLyphy only on Windows
if test $_os = WINNT; then
libo_CHECK_SYSTEM_MODULE([glyphy], [GLYPHY], [glyphy >= 0.12.0], ["-I${WORKDIR}/UnpackedTarball/glyphy/src"])
fi
dnl ===================================================================
dnl Check for system odbc
dnl ===================================================================
......
......@@ -55,7 +55,6 @@ export FREEHAND_TARBALL := libfreehand-0.1.1.tar.bz2
export FREETYPE_TARBALL := dbf2caca1d3afd410a29217a9809d397-freetype-2.4.8.tar.bz2
export GLEW_TARBALL := 3941e9cab2f4f9d8faee3e8d57ae7664-glew-1.12.0.zip
export GLM_TARBALL := bae83fa5dc7f081768daace6e199adc3-glm-0.9.4.6-libreoffice.zip
export GLYPHY_TARBALL := 5d303fb955beb9bf112267316ca9d021-glyphy-0.2.0.tar.bz2
export GRAPHITE_TARBALL := 3069842a88b8f40c6b83ad2850cda293-graphite2-minimal-1.3.9.tgz
export HARFBUZZ_MD5SUM := 5986e1bfcd983d1f6caa53ef64c4abc5
export HARFBUZZ_TARBALL := harfbuzz-1.3.2.tar.bz2
......
......@@ -46,7 +46,6 @@ $(eval $(call gb_Module_add_moduledirs,external,\
$(call gb_Helper_optional,FREETYPE,freetype) \
$(call gb_Helper_optional,GLEW,glew) \
$(call gb_Helper_optional,GLM,glm) \
$(call gb_Helper_optional,GLYPHY,glyphy) \
$(call gb_Helper_optional,GRAPHITE,graphite) \
$(call gb_Helper_optional,HARFBUZZ,harfbuzz) \
$(call gb_Helper_optional,HSQLDB,hsqldb) \
......
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_ExternalPackage_ExternalPackage,glyphy,glyphy))
$(eval $(call gb_ExternalPackage_use_external_project,glyphy,glyphy))
ifeq ($(OS),MACOSX)
$(eval $(call gb_ExternalPackage_add_file,glyphy,$(LIBO_LIB_FOLDER)/libglyphy.dylib,src/.libs/libglyphy.dylib))
else ifeq ($(OS),WNT)
# We build a static archive with MSVC, so nothing to add
else ifeq ($(DISABLE_DYNLOADING),)
$(eval $(call gb_ExternalPackage_add_file,glyphy,$(LIBO_LIB_FOLDER)/libglyphy.so.0,src/.libs/libglyphy.so.0.0.0))
endif
# vim: set noet sw=4 ts=4:
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_ExternalProject_ExternalProject,glyphy))
$(eval $(call gb_ExternalProject_use_autoconf,glyphy,build))
$(eval $(call gb_ExternalProject_register_targets,glyphy,\
build \
))
$(eval $(call gb_ExternalProject_use_externals,glyphy, \
glew \
))
$(call gb_ExternalProject_get_state_target,glyphy,build) :
$(call gb_ExternalProject_run,build,\
$(if $(filter MSC,$(COM)),CPPFLAGS=-D_USE_MATH_DEFINES) \
MAKE=$(MAKE) ./configure \
--with-pic \
$(if $(DISABLE_DYNLOADING), \
--enable-static --disable-shared \
, \
--enable-shared --disable-static \
) \
$(if $(filter MACOSX,$(OS)),--prefix=/@.__________________________________________________OOO) \
$(if $(CROSS_COMPILING),--build=$(BUILD_PLATFORM) --host=$(HOST_PLATFORM)) \
&& $(if $(verbose),V=1) \
$(MAKE) \
)
# vim: set noet sw=4 ts=4:
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
include $(module_directory)/../../solenv/gbuild/partial_build.mk
# vim: set noet sw=4 ts=4:
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_Module_Module,glyphy))
$(eval $(call gb_Module_add_targets,glyphy,\
UnpackedTarball_glyphy \
))
$(eval $(call gb_Module_add_targets,glyphy,\
ExternalPackage_glyphy \
ExternalProject_glyphy \
))
# vim: set noet sw=4 ts=4:
GLyphy is a text renderer that uses OpenGL
https://github.com/behdad/glyphy
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
$(eval $(call gb_UnpackedTarball_UnpackedTarball,glyphy))
$(eval $(call gb_UnpackedTarball_set_tarball,glyphy,$(GLYPHY_TARBALL)))
$(eval $(call gb_UnpackedTarball_set_patchlevel,glyphy,1))
$(eval $(call gb_UnpackedTarball_add_patches,glyphy,\
external/glyphy/glyphy-upstream.patch.1 \
external/glyphy/glyphy-windows.patch.1 \
))
# vim: set noet sw=4 ts=4:
From d6d6c61c8d0e336c34ba3f5d9adbe923ffa1cbe3 Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod <behdad@behdad.org>
Date: Thu, 6 Aug 2015 15:34:38 +0100
Subject: [PATCH 2/6] Implement more robust winding-direction algorithm
Fixes 'p' in Comic Sans Bold for example. That font has many
self-intersecting contours. The one in 'p' was causing complete
winding direction reversal using old algorithm. Implement area-based
algorithm.
---
src/glyphy-outline.cc | 67 ++++++++++-----------------------------------------
1 file changed, 13 insertions(+), 54 deletions(-)
diff --git a/src/glyphy-outline.cc b/src/glyphy-outline.cc
index 3543f3b..ef71247 100644
--- a/src/glyphy-outline.cc
+++ b/src/glyphy-outline.cc
@@ -55,65 +55,24 @@ winding (const glyphy_arc_endpoint_t *endpoints,
/*
* Algorithm:
*
- * - Find the lowest-x part of the contour,
- * - If the point is an endpoint:
- * o compare the angle of the incoming and outgoing edges of that point
- * to find out whether it's CW or CCW,
- * - Otherwise, compare the y of the two endpoints of the arc with lowest-x point.
- *
- * Note:
- *
- * We can use a simpler algorithm here: Act as if arcs are lines, then use the
- * triangle method to calculate the signed area of the contour and get the sign.
- * It should work for all cases we care about. The only case failing would be
- * that of two endpoints and two arcs. But we can even special-case that.
+ * - Approximate arcs with triangles passing through the mid- and end-points,
+ * - Calculate the area of the contour,
+ * - Return sign.
*/
- unsigned int corner = 1;
- for (unsigned int i = 2; i < num_endpoints; i++)
- if (endpoints[i].p.x < endpoints[corner].p.x ||
- (endpoints[i].p.x == endpoints[corner].p.x &&
- endpoints[i].p.y < endpoints[corner].p.y))
- corner = i;
-
- double min_x = endpoints[corner].p.x;
- int winner = -1;
- Point p0 (0, 0);
- for (unsigned int i = 0; i < num_endpoints; i++) {
- const glyphy_arc_endpoint_t &endpoint = endpoints[i];
- if (endpoint.d == GLYPHY_INFINITY || endpoint.d == 0 /* arcs only, not lines */) {
- p0 = endpoint.p;
- continue;
- }
- Arc arc (p0, endpoint.p, endpoint.d);
- p0 = endpoint.p;
+ double area = 0;
+ for (unsigned int i = 1; i < num_endpoints; i++)
+ {
+ const glyphy_point_t &p0 = endpoints[i - 1].p;
+ const glyphy_point_t &p1 = endpoints[i].p;
+ double d = endpoints[i].d;
- Point c = arc.center ();
- double r = arc.radius ();
- if (c.x - r < min_x && arc.wedge_contains_point (c - Vector (r, 0))) {
- min_x = c.x - r;
- winner = i;
- }
- }
+ assert (d != GLYPHY_INFINITY);
- if (winner == -1)
- {
- // Corner is lowest-x. Find the tangents of the two arcs connected to the
- // corner and compare the tangent angles to get contour direction.
- const glyphy_arc_endpoint_t ethis = endpoints[corner];
- const glyphy_arc_endpoint_t eprev = endpoints[corner - 1];
- const glyphy_arc_endpoint_t enext = endpoints[corner < num_endpoints - 1 ? corner + 1 : 1];
- double in = (-Arc (eprev.p, ethis.p, ethis.d).tangents ().second).angle ();
- double out = (+Arc (ethis.p, enext.p, enext.d).tangents ().first ).angle ();
- return out > in;
+ area += p0.x*p1.y - p0.y*p1.x;
+ area -= .5 * d * ((p1.x-p0.x)*(p1.x-p0.x) + (p1.y-p0.y)*(p1.y-p0.y));
}
- else
- {
- // Easy.
- return endpoints[winner].d < 0;
- }
-
- return false;
+ return area < 0;
}
--
2.5.0
From 644c5bab6e7f0e5af8f42fa7a8075372716c66d3 Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod <behdad@behdad.org>
Date: Thu, 6 Aug 2015 15:49:37 +0100
Subject: [PATCH 3/6] Start handling fully-degenerate curves
---
src/glyphy-arcs-bezier.hh | 7 +++++++
src/glyphy-geometry.hh | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/src/glyphy-arcs-bezier.hh b/src/glyphy-arcs-bezier.hh
index ab729cb..32b7c8c 100644
--- a/src/glyphy-arcs-bezier.hh
+++ b/src/glyphy-arcs-bezier.hh
@@ -103,6 +103,13 @@ class ArcsBezierApproximatorSpringSystem
double *perror,
unsigned int max_segments = 100)
{
+ /* Handle fully-degenerate cases. */
+ Vector v1 (b.p1 - b.p0);
+ Vector v2 (b.p2 - b.p0);
+ Vector v3 (b.p3 - b.p0);
+ if (fabs (v1.cross(v2)) < GLYPHY_EPSILON && fabs (v2.cross(v3)) < GLYPHY_EPSILON)
+ ;//TODO
+
std::vector<double> t;
std::vector<double> e;
double max_e, min_e;
diff --git a/src/glyphy-geometry.hh b/src/glyphy-geometry.hh
index f5f6003..3c60856 100644
--- a/src/glyphy-geometry.hh
+++ b/src/glyphy-geometry.hh
@@ -99,6 +99,7 @@ struct Vector {
inline const Vector normal (void) const; /* ortho().normalized() */
inline double angle (void) const;
+ inline double cross (const Vector &other) const;
inline const Vector rebase (const Vector &bx, const Vector &by) const;
inline const Vector rebase (const Vector &bx) const;
@@ -345,6 +346,9 @@ inline double Vector::angle (void) const {
return atan2 (dy, dx);
}
+inline double Vector::cross (const Vector &other) const {
+ return dx * other.dy - dy * other.dx;
+}
inline const Vector Vector::rebase (const Vector &bx,
const Vector &by) const {
return Vector (*this * bx, *this * by);
--
2.5.0
From 5667ab11a3d5f57bb89c4e8970d26b940d36964a Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod <behdad@behdad.org>
Date: Thu, 6 Aug 2015 15:51:15 +0100
Subject: [PATCH 4/6] Simplify winding()
---
src/glyphy-outline.cc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/glyphy-outline.cc b/src/glyphy-outline.cc
index ef71247..7fded28 100644
--- a/src/glyphy-outline.cc
+++ b/src/glyphy-outline.cc
@@ -69,8 +69,8 @@ winding (const glyphy_arc_endpoint_t *endpoints,
assert (d != GLYPHY_INFINITY);
- area += p0.x*p1.y - p0.y*p1.x;
- area -= .5 * d * ((p1.x-p0.x)*(p1.x-p0.x) + (p1.y-p0.y)*(p1.y-p0.y));
+ area += Vector(p0).cross (Vector(p1));
+ area -= .5 * d * (Point(p1) - Point(p0)).len2 ();
}
return area < 0;
}
--
2.5.0
From 16fa0a713295a76f3075e6732007dca2dd38d11e Mon Sep 17 00:00:00 2001
From: Behdad Esfahbod <behdad@behdad.org>
Date: Thu, 6 Aug 2015 16:00:19 +0100
Subject: [PATCH 5/6] Better handle fully-degenerate curves
---
src/glyphy-arcs-bezier.hh | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/glyphy-arcs-bezier.hh b/src/glyphy-arcs-bezier.hh
index 32b7c8c..ac210c0 100644
--- a/src/glyphy-arcs-bezier.hh
+++ b/src/glyphy-arcs-bezier.hh
@@ -108,7 +108,14 @@ class ArcsBezierApproximatorSpringSystem
Vector v2 (b.p2 - b.p0);
Vector v3 (b.p3 - b.p0);
if (fabs (v1.cross(v2)) < GLYPHY_EPSILON && fabs (v2.cross(v3)) < GLYPHY_EPSILON)
- ;//TODO
+ {
+ /* Curve has no area. If endpoints are NOT the same, replace with single
+ * line segment. Otherwise fully skip. */
+ arcs.clear ();
+ if (b.p0 != b.p1)
+ arcs.push_back (Arc (b.p0, b.p1, 0));
+ return;
+ }
std::vector<double> t;
std::vector<double> e;
--
2.5.0
This diff is collapsed.
......@@ -186,12 +186,6 @@ $(eval $(call gb_CppunitTest_use_system_win32_libs,vcl_wmf_test,\
#$(eval $(call gb_CppunitTest_add_nativeres,vcl_wmf_test,vcl/salsrc))
endif
ifeq ($(OS), WNT)
$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\
glyphy \
))
endif
ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
$(eval $(call gb_CppunitTest_add_libs,vcl_wmf_test,\
-lm $(DLOPEN_LIBS) \
......
......@@ -41,7 +41,6 @@ $(eval $(call gb_Library_set_include,vcl,\
$$(INCLUDE) \
-I$(SRCDIR)/vcl/inc \
$(if $(filter WNTGCC,$(OS)$(COM)),-I$(MINGW_SYSROOT)/include/gdiplus) \
$(if $(filter WNT,$(OS)),-I$(SRCDIR)/vcl/inc/glyphy/demo) \
))
$(eval $(call gb_Library_add_defs,vcl,\
......@@ -699,7 +698,6 @@ endif
ifeq ($(OS),WNT)
$(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/glyphy/demo \
vcl/opengl/win/gdiimpl \
vcl/opengl/win/WinDeviceInfo \
vcl/opengl/win/blocklist_parser \
......@@ -748,12 +746,6 @@ $(eval $(call gb_Library_use_system_win32_libs,vcl,\
$(eval $(call gb_Library_add_nativeres,vcl,vcl/salsrc))
endif
ifeq ($(OS), WNT)
$(eval $(call gb_Library_use_externals,vcl,\
glyphy \
))
endif
ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS)))
$(eval $(call gb_Library_add_libs,vcl,\
-lm $(DLOPEN_LIBS) \
......
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/config.h>
#include <prewin.h>
#include <postwin.h>
#include "demo/demo-atlas.cc"
#include "demo/demo-buffer.cc"
#include "demo/demo-font.cc"
#include "demo/demo-shader.cc"
#include "demo/matrix4x4.c"
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "demo-atlas.h"
struct demo_atlas_t {
unsigned int refcount;
GLuint tex_unit;
GLuint tex_name;
GLuint tex_w;
GLuint tex_h;
GLuint item_w;
GLuint item_h_q; /* height quantum */
GLuint cursor_x;
GLuint cursor_y;
};
demo_atlas_t *
demo_atlas_create (unsigned int w,
unsigned int h,
unsigned int item_w,
unsigned int item_h_quantum)
{
TRACE();
demo_atlas_t *at = static_cast<demo_atlas_t *>(calloc (1, sizeof (demo_atlas_t)));
at->refcount = 1;
glGetIntegerv (GL_ACTIVE_TEXTURE, reinterpret_cast<GLint *>(&at->tex_unit));
glGenTextures (1, &at->tex_name);
at->tex_w = w;
at->tex_h = h;
at->item_w = item_w;
at->item_h_q = item_h_quantum;
at->cursor_x = 0;
at->cursor_y = 0;
demo_atlas_bind_texture (at);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl(TexImage2D) (GL_TEXTURE_2D, 0, GL_RGBA, at->tex_w, at->tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
return at;
}
demo_atlas_t *
demo_atlas_reference (demo_atlas_t *at)
{
if (at) at->refcount++;
return at;
}
void
demo_atlas_destroy (demo_atlas_t *at)
{
if (!at || --at->refcount)
return;
glDeleteTextures (1, &at->tex_name);
free (at);
}
void
demo_atlas_bind_texture (demo_atlas_t *at)
{
glActiveTexture (at->tex_unit);
glBindTexture (GL_TEXTURE_2D, at->tex_name);
}
void
demo_atlas_set_uniforms (demo_atlas_t *at)
{
GLuint program;
glGetIntegerv (GL_CURRENT_PROGRAM, reinterpret_cast<GLint *>(&program));
glUniform4i (glGetUniformLocation (program, "u_atlas_info"),
at->tex_w, at->tex_h, at->item_w, at->item_h_q);
glUniform1i (glGetUniformLocation (program, "u_atlas_tex"), at->tex_unit - GL_TEXTURE0);
}
void
demo_atlas_alloc (demo_atlas_t *at,
glyphy_rgba_t *data,
unsigned int len,
unsigned int *px,
unsigned int *py)
{
GLuint w, h, x = 0, y = 0;
w = at->item_w;
h = (len + w - 1) / w;
if (at->cursor_y + h > at->tex_h) {
/* Go to next column */
at->cursor_x += at->item_w;
at->cursor_y = 0;
}
if (at->cursor_x + w <= at->tex_w &&
at->cursor_y + h <= at->tex_h)
{
x = at->cursor_x;
y = at->cursor_y;
at->cursor_y += (h + at->item_h_q - 1) & ~(at->item_h_q - 1);
} else
die ("Ran out of atlas memory");
demo_atlas_bind_texture (at);
if (w * h == len)
gl(TexSubImage2D) (GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
else {
gl(TexSubImage2D) (GL_TEXTURE_2D, 0, x, y, w, h - 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
/* Upload the last row separately */
gl(TexSubImage2D) (GL_TEXTURE_2D, 0, x, y + h - 1, len - (w * (h - 1)), 1, GL_RGBA, GL_UNSIGNED_BYTE,
data + w * (h - 1));
}
*px = x / at->item_w;
*py = y / at->item_h_q;
}
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "demo-buffer.h"
struct demo_buffer_t {
unsigned int refcount;
glyphy_point_t cursor;
std::vector<glyph_vertex_t> *vertices;
glyphy_extents_t ink_extents;
glyphy_extents_t logical_extents;
bool dirty;
GLuint buf_name;
};
demo_buffer_t *
demo_buffer_create (void)
{
demo_buffer_t *buffer = static_cast<demo_buffer_t *>(calloc (1, sizeof (demo_buffer_t)));
buffer->refcount = 1;
buffer->vertices = new std::vector<glyph_vertex_t>;
glGenBuffers (1, &buffer->buf_name);
demo_buffer_clear (buffer);
return buffer;
}
demo_buffer_t *
demo_buffer_reference (demo_buffer_t *buffer)
{
if (buffer) buffer->refcount++;
return buffer;
}
void
demo_buffer_destroy (demo_buffer_t *buffer)
{
if (!buffer || --buffer->refcount)
return;
glDeleteBuffers (1, &buffer->buf_name);
delete buffer->vertices;
free (buffer);
}
void
demo_buffer_clear (demo_buffer_t *buffer)
{
buffer->vertices->clear ();
glyphy_extents_clear (&buffer->ink_extents);
glyphy_extents_clear (&buffer->logical_extents);
buffer->dirty = true;
}
void
demo_buffer_extents (demo_buffer_t *buffer,
glyphy_extents_t *ink_extents,
glyphy_extents_t *logical_extents)
{
if (ink_extents)
*ink_extents = buffer->ink_extents;
if (logical_extents)
*logical_extents = buffer->logical_extents;
}
void
demo_buffer_move_to (demo_buffer_t *buffer,
const glyphy_point_t *p)
{
buffer->cursor = *p;
}
void
demo_buffer_current_point (demo_buffer_t *buffer,
glyphy_point_t *p)
{
*p = buffer->cursor;
}
void
demo_buffer_add_text (demo_buffer_t *buffer,
const char *utf8,
demo_font_t *font,
double font_size)
{
#ifndef _WIN32
FT_Face face = demo_font_get_face (font);
#else
HDC hdc = demo_font_get_face (font);
#endif
glyphy_point_t top_left = buffer->cursor;
buffer->cursor.y += font_size /* * font->ascent */;
unsigned int unicode;
for (const unsigned char *p = reinterpret_cast<const unsigned char *>(utf8); *p; p++) {
if (*p < 128) {
unicode = *p;
} else {
unsigned int j;
if (*p < 0xE0) {
unicode = *p & ~0xE0;
j = 1;
} else if (*p < 0xF0) {
unicode = *p & ~0xF0;
j = 2;
} else {
unicode = *p & ~0xF8;
j = 3;
continue;
}
p++;
for (; j && *p; j--, p++)
unicode = (unicode << 6) | (*p & ~0xC0);
p--;
}
if (unicode == '\n') {
buffer->cursor.y += font_size;
buffer->cursor.x = top_left.x;
continue;
}
#ifndef _WIN32
unsigned int glyph_index = FT_Get_Char_Index (face, unicode);
#else
wchar_t wc = unicode; /* FIXME: What about non-BMP chars? */
WORD glyph_index;
if (GetGlyphIndicesW (hdc, &wc, 1, &glyph_index, GGI_MARK_NONEXISTING_GLYPHS) == GDI_ERROR)
die ("GetGlyphIndicesW failed");
#endif
glyph_info_t gi;
demo_font_lookup_glyph (font, glyph_index, &gi);
/* Update ink extents */
glyphy_extents_t ink_extents;
demo_shader_add_glyph_vertices (buffer->cursor, font_size, &gi, buffer->vertices, &ink_extents);
glyphy_extents_extend (&buffer->ink_extents, &ink_extents);
/* Update logical extents */
glyphy_point_t corner;
corner.x = buffer->cursor.x;
corner.y = buffer->cursor.y - font_size;
glyphy_extents_add (&buffer->logical_extents, &corner);
corner.x = buffer->cursor.x + font_size * gi.advance;
corner.y = buffer->cursor.y;
glyphy_extents_add (&buffer->logical_extents, &corner);
buffer->cursor.x += font_size * gi.advance;
}
buffer->dirty = true;
}
void
demo_buffer_draw (demo_buffer_t *buffer)
{
GLint program;
glGetIntegerv (GL_CURRENT_PROGRAM, &program);
GLuint a_glyph_vertex_loc = glGetAttribLocation (program, "a_glyph_vertex");
glBindBuffer (GL_ARRAY_BUFFER, buffer->buf_name);
if (buffer->dirty) {
glBufferData (GL_ARRAY_BUFFER, sizeof (glyph_vertex_t) * buffer->vertices->size (), &(*buffer->vertices)[0], GL_STATIC_DRAW);
buffer->dirty = false;
}
glEnableVertexAttribArray (a_glyph_vertex_loc);
glVertexAttribPointer (a_glyph_vertex_loc, 4, GL_FLOAT, GL_FALSE, sizeof (glyph_vertex_t), nullptr);
glDrawArrays (GL_TRIANGLES, 0, buffer->vertices->size ());
glDisableVertexAttribArray (a_glyph_vertex_loc);
}
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "demo-font.h"
#ifndef _WIN32
#include <glyphy-freetype.h>
#endif
#ifdef _WIN32
#include <glyphy-windows.h>
#endif
#include <map>
#include <vector>
typedef std::map<unsigned int, glyph_info_t> glyph_cache_t;
struct demo_font_t {
unsigned int refcount;
#ifndef _WIN32
FT_Face face;
#endif
#ifdef _WIN32
HDC face; /* A memory DC that has the font instance selected into it */
#endif
glyph_cache_t *glyph_cache;
demo_atlas_t *atlas;
glyphy_arc_accumulator_t *acc;
/* stats */
unsigned int num_glyphs;
double sum_error;
unsigned int sum_endpoints;
double sum_fetch;
unsigned int sum_bytes;
};
demo_font_t *
demo_font_create (
#ifndef _WIN32
FT_Face face,
#endif
#ifdef _WIN32
HDC face,
#endif
demo_atlas_t *atlas)
{
demo_font_t *font = static_cast<demo_font_t *>(calloc (1, sizeof (demo_font_t)));
font->refcount = 1;
font->face = face;
font->glyph_cache = new glyph_cache_t ();
font->atlas = demo_atlas_reference (atlas);
font->acc = glyphy_arc_accumulator_create ();
font->num_glyphs = 0;
font->sum_error = 0;
font->sum_endpoints = 0;
font->sum_fetch = 0;
font->sum_bytes = 0;
return font;
}
demo_font_t *
demo_font_reference (demo_font_t *font)
{
if (font) font->refcount++;
return font;
}
void
demo_font_destroy (demo_font_t *font)
{
if (!font || --font->refcount)
return;
glyphy_arc_accumulator_destroy (font->acc);
demo_atlas_destroy (font->atlas);
delete font->glyph_cache;
free (font);
}
#ifndef _WIN32
FT_Face
#endif
#ifdef _WIN32
HDC
#endif
demo_font_get_face (demo_font_t *font)
{
return font->face;
}
demo_atlas_t *
demo_font_get_atlas (demo_font_t *font)
{
return font->atlas;
}
static glyphy_bool_t
accumulate_endpoint (glyphy_arc_endpoint_t *endpoint,
std::vector<glyphy_arc_endpoint_t> *endpoints)
{
endpoints->push_back (*endpoint);
return true;
}
static void
encode_glyph (demo_font_t *font,
unsigned int glyph_index,
double tolerance_per_em,
glyphy_rgba_t *buffer,
unsigned int buffer_len,
unsigned int *output_len,
unsigned int *nominal_width,
unsigned int *nominal_height,
glyphy_extents_t *extents,
double *advance)
{
/* Used for testing only */
#define SCALE (1. * (1 << 0))
#ifndef _WIN32
FT_Face face = font->face;
if (FT_Err_Ok != FT_Load_Glyph (face,
glyph_index,
FT_LOAD_NO_BITMAP |
FT_LOAD_NO_HINTING |
FT_LOAD_NO_AUTOHINT |
FT_LOAD_NO_SCALE |
FT_LOAD_LINEAR_DESIGN |
FT_LOAD_IGNORE_TRANSFORM))
die ("Failed loading FreeType glyph");
if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
die ("FreeType loaded glyph format is not outline");
unsigned int upem = face->units_per_EM;
double tolerance = upem * tolerance_per_em; /* in font design units */
double faraway = double (upem) / (MIN_FONT_SIZE * M_SQRT2);
std::vector<glyphy_arc_endpoint_t> endpoints;
glyphy_arc_accumulator_reset (font->acc);
glyphy_arc_accumulator_set_tolerance (font->acc, tolerance);
glyphy_arc_accumulator_set_callback (font->acc,
(glyphy_arc_endpoint_accumulator_callback_t) accumulate_endpoint,
&endpoints);
if (FT_Err_Ok != glyphy_freetype(outline_decompose) (&face->glyph->outline, font->acc))
die ("Failed converting glyph outline to arcs");
#endif
#ifdef _WIN32
HDC hdc = font->face;
GLYPHMETRICS glyph_metrics;
MAT2 matrix;
matrix.eM11.value = 1;
matrix.eM11.fract = 0;
matrix.eM12.value = 0;
matrix.eM12.fract = 0;
matrix.eM21.value = 0;
matrix.eM21.fract = 0;
matrix.eM22.value = 1;
matrix.eM22.fract = 0;
DWORD size = GetGlyphOutlineW (hdc, glyph_index, GGO_NATIVE|GGO_GLYPH_INDEX, &glyph_metrics, 0, nullptr, &matrix);
if (size == GDI_ERROR)
die ("GetGlyphOutlineW failed");
std::vector<char> buf(size);
size = GetGlyphOutlineW (hdc, glyph_index, GGO_NATIVE|GGO_GLYPH_INDEX, &glyph_metrics, size, buf.data(), &matrix);
if (size == GDI_ERROR)
die ("GetGlyphOutlineW failed");
size = GetGlyphOutlineW (hdc, glyph_index, GGO_METRICS|GGO_GLYPH_INDEX, &glyph_metrics, 0, nullptr, &matrix);
if (size == GDI_ERROR)
die ("GetGlyphOutlineW failed");
OUTLINETEXTMETRICW outline_text_metric;
if (!GetOutlineTextMetricsW (hdc, sizeof (OUTLINETEXTMETRICW), &outline_text_metric))
die ("GetOutlineTextMetricsW failed");
unsigned int upem = outline_text_metric.otmEMSquare;
double tolerance = upem * tolerance_per_em; /* in font design units */
double faraway = double (upem) / (MIN_FONT_SIZE * M_SQRT2);
std::vector<glyphy_arc_endpoint_t> endpoints;
glyphy_arc_accumulator_reset (font->acc);
glyphy_arc_accumulator_set_tolerance (font->acc, tolerance);
glyphy_arc_accumulator_set_callback (font->acc,
reinterpret_cast<glyphy_arc_endpoint_accumulator_callback_t>(accumulate_endpoint),
&endpoints);
if (0 != glyphy_windows(outline_decompose) (reinterpret_cast<TTPOLYGONHEADER *>(buf.data()), buf.size(), font->acc))
die ("Failed converting glyph outline to arcs");
#endif
assert (glyphy_arc_accumulator_get_error (font->acc) <= tolerance);
if (endpoints.size ())
{
#if 0
/* Technically speaking, we want the following code,
* however, crappy fonts have crappy flags. So we just
* fixup unconditionally... */
if (face->glyph->outline.flags & FT_OUTLINE_EVEN_ODD_FILL)
glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false);
else if (face->glyph->outline.flags & FT_OUTLINE_REVERSE_FILL)
glyphy_outline_reverse (&endpoints[0], endpoints.size ());
#else
glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false);
#endif
}
if (SCALE != 1.)
for (std::vector<glyphy_arc_endpoint_t>::size_type i = 0; i < endpoints.size (); i++)
{
endpoints[i].p.x /= SCALE;
endpoints[i].p.y /= SCALE;
}
double avg_fetch_achieved;
if (!glyphy_arc_list_encode_blob (endpoints.size () ? &endpoints[0] : nullptr, endpoints.size (),
buffer,
buffer_len,
faraway / SCALE,
4, /* UNUSED */
&avg_fetch_achieved,
output_len,
nominal_width,
nominal_height,
extents))
die ("Failed encoding arcs");
glyphy_extents_scale (extents, 1. / upem, 1. / upem);
glyphy_extents_scale (extents, SCALE, SCALE);
#ifndef _WIN32
*advance = face->glyph->metrics.horiAdvance / (double) upem;
#endif
#ifdef _WIN32
*advance = glyph_metrics.gmCellIncX / (double) upem; /* ??? */
#endif
if (false)
LOGI ("gid%3u: endpoints%3d; err%3g%%; tex fetch%4.1f; mem%4.1fkb\n",
glyph_index,
(unsigned int) glyphy_arc_accumulator_get_num_endpoints (font->acc),
round (100 * glyphy_arc_accumulator_get_error (font->acc) / tolerance),
avg_fetch_achieved,
(*output_len * sizeof (glyphy_rgba_t)) / 1024.);
font->num_glyphs++;
font->sum_error += glyphy_arc_accumulator_get_error (font->acc) / tolerance;
font->sum_endpoints += glyphy_arc_accumulator_get_num_endpoints (font->acc);
font->sum_fetch += avg_fetch_achieved;
font->sum_bytes += (*output_len * sizeof (glyphy_rgba_t));
}
static void
demo_font_upload_glyph (demo_font_t *font,
unsigned int glyph_index,
glyph_info_t *glyph_info)
{
glyphy_rgba_t buffer[4096 * 16];
unsigned int output_len;
encode_glyph (font,
glyph_index,
TOLERANCE,
buffer, ARRAY_LEN (buffer),
&output_len,
&glyph_info->nominal_w,
&glyph_info->nominal_h,
&glyph_info->extents,
&glyph_info->advance);
glyph_info->is_empty = glyphy_extents_is_empty (&glyph_info->extents);
if (!glyph_info->is_empty)
demo_atlas_alloc (font->atlas, buffer, output_len,
&glyph_info->atlas_x, &glyph_info->atlas_y);
}
void
demo_font_lookup_glyph (demo_font_t *font,
unsigned int glyph_index,
glyph_info_t *glyph_info)
{
if (font->glyph_cache->find (glyph_index) == font->glyph_cache->end ()) {
demo_font_upload_glyph (font, glyph_index, glyph_info);
(*font->glyph_cache)[glyph_index] = *glyph_info;
} else
*glyph_info = (*font->glyph_cache)[glyph_index];
}
void
demo_font_print_stats (demo_font_t *font)
{
(void) font;
LOGI ("%3d glyphs; avg num endpoints%6.2f; avg error%5.1f%%; avg tex fetch%5.2f; avg %5.2fkb per glyph\n",
font->num_glyphs,
(double) font->sum_endpoints / font->num_glyphs,
100. * font->sum_error / font->num_glyphs,
font->sum_fetch / font->num_glyphs,
font->sum_bytes / 1024. / font->num_glyphs);
}
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "demo-shader.h"
#include "demo-atlas-glsl.h"
#include "demo-vshader-glsl.h"
#include "demo-fshader-glsl.h"
static unsigned int
glyph_encode (unsigned int atlas_x , /* 7 bits */
unsigned int atlas_y, /* 7 bits */
unsigned int corner_x, /* 1 bit */
unsigned int corner_y, /* 1 bit */
unsigned int nominal_w, /* 6 bits */
unsigned int nominal_h /* 6 bits */)
{
assert (0 == (atlas_x & ~0x7F));
assert (0 == (atlas_y & ~0x7F));
assert (0 == (corner_x & ~1));
assert (0 == (corner_y & ~1));
assert (0 == (nominal_w & ~0x3F));
assert (0 == (nominal_h & ~0x3F));
unsigned int x = (((atlas_x << 6) | nominal_w) << 1) | corner_x;
unsigned int y = (((atlas_y << 6) | nominal_h) << 1) | corner_y;
return (x << 16) | y;
}
static void
glyph_vertex_encode (double x, double y,
unsigned int corner_x, unsigned int corner_y,
const glyph_info_t *gi,
glyph_vertex_t *v)
{
unsigned int encoded = glyph_encode (gi->atlas_x, gi->atlas_y,
corner_x, corner_y,
gi->nominal_w, gi->nominal_h);
v->x = x;
v->y = y;
v->g16hi = encoded >> 16;
v->g16lo = encoded & 0xFFFF;
}
void
demo_shader_add_glyph_vertices (const glyphy_point_t &p,
double font_size,
glyph_info_t *gi,
std::vector<glyph_vertex_t> *vertices,
glyphy_extents_t *extents)
{
if (gi->is_empty)
return;
glyph_vertex_t v[4];
#define ENCODE_CORNER(_cx, _cy) \
do { \
double _vx = p.x + font_size * ((1-_cx) * gi->extents.min_x + _cx * gi->extents.max_x); \
double _vy = p.y - font_size * ((1-_cy) * gi->extents.min_y + _cy * gi->extents.max_y); \
glyph_vertex_encode (_vx, _vy, _cx, _cy, gi, &v[_cx * 2 + _cy]); \
} while (false)
ENCODE_CORNER (0, 0);
ENCODE_CORNER (0, 1);
ENCODE_CORNER (1, 0);
ENCODE_CORNER (1, 1);
#undef ENCODE_CORNER
vertices->push_back (v[0]);
vertices->push_back (v[1]);
vertices->push_back (v[2]);
vertices->push_back (v[1]);
vertices->push_back (v[2]);
vertices->push_back (v[3]);
if (extents) {
glyphy_extents_clear (extents);
for (unsigned int i = 0; i < 4; i++) {
glyphy_point_t p2 = {v[i].x, v[i].y};
glyphy_extents_add (extents, &p2);
}
}
}
static GLuint
compile_shader (GLenum type,
GLsizei count,
const GLchar** sources)
{
TRACE();
GLuint shader;
GLint compiled;
if (!(shader = glCreateShader (type)))
return shader;
glShaderSource (shader, count, sources, nullptr);
glCompileShader (shader);
glGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
if (!compiled) {
GLint info_len = 0;
LOGW ("%s shader failed to compile\n",
type == GL_VERTEX_SHADER ? "Vertex" : "Fragment");
glGetShaderiv (shader, GL_INFO_LOG_LENGTH, &info_len);
if (info_len > 0) {
char *info_log = static_cast<char*>(malloc (info_len));
glGetShaderInfoLog (shader, info_len, nullptr, info_log);
LOGW ("%s\n", info_log);
free (info_log);
}
abort ();
}
return shader;
}
static GLuint
link_program (GLuint vshader,
GLuint fshader)
{
TRACE();
GLuint program;
GLint linked;
program = glCreateProgram ();
glAttachShader (program, vshader);
glAttachShader (program, fshader);
glLinkProgram (program);
glDeleteShader (vshader);
glDeleteShader (fshader);
glGetProgramiv (program, GL_LINK_STATUS, &linked);
if (!linked) {
GLint info_len = 0;
LOGW ("Program failed to link\n");
glGetProgramiv (program, GL_INFO_LOG_LENGTH, &info_len);
if (info_len > 0) {
char *info_log = static_cast<char*>(malloc (info_len));
glGetProgramInfoLog (program, info_len, nullptr, info_log);
LOGW ("%s\n", info_log);
free (info_log);
}
abort ();
}
return program;
}
#ifdef GL_ES_VERSION_2_0
# define GLSL_HEADER_STRING \
"#extension GL_OES_standard_derivatives : enable\n" \
"precision highp float;\n" \
"precision highp int;\n"
#else
# define GLSL_HEADER_STRING \
"#version 110\n"
#endif
GLuint
demo_shader_create_program (void)
{
TRACE();
GLuint vshader, fshader, program;
const GLchar *vshader_sources[] = {GLSL_HEADER_STRING,
demo_vshader_glsl};
vshader = compile_shader (GL_VERTEX_SHADER, ARRAY_LEN (vshader_sources), vshader_sources);
const GLchar *fshader_sources[] = {GLSL_HEADER_STRING,
demo_atlas_glsl,
glyphy_common_shader_source (),
"#define GLYPHY_SDF_PSEUDO_DISTANCE 1\n",
glyphy_sdf_shader_source (),
demo_fshader_glsl};
fshader = compile_shader (GL_FRAGMENT_SHADER, ARRAY_LEN (fshader_sources), fshader_sources);
program = link_program (vshader, fshader);
return program;
}
This diff is collapsed.
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_VCL_INC_GLYPHY_DEMO_HXX
#define INCLUDED_VCL_INC_GLYPHY_DEMO_HXX
#include "demo-atlas.h"
#include "demo-buffer.h"
#include "demo-font.h"
#include "demo-shader.h"
#include "matrix4x4.h"
#endif // INCLUDED_VCL_INC_GLYPHY_DEMO_HXX
static const char *demo_atlas_glsl =
"uniform sampler2D u_atlas_tex;\n"
"uniform ivec4 u_atlas_info;\n"
"\n"
"#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos\n"
"#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos\n"
"#define GLYPHY_DEMO_EXTRA_ARGS , u_atlas_tex, u_atlas_info, gi.atlas_pos\n"
"\n"
"vec4\n"
"glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)\n"
"{\n"
" ivec2 item_geom = _atlas_info.zw;\n"
" vec2 pos = (vec2 (_atlas_pos.xy * item_geom +\n"
" ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +\n"
" + vec2 (.5, .5)) / vec2(_atlas_info.xy);\n"
" return texture2D (_tex, pos);\n"
"}\n"
;
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod, Maysum Panju
*/
#ifndef DEMO_ATLAS_H
#define DEMO_ATLAS_H
#include "demo-common.h"
typedef struct demo_atlas_t demo_atlas_t;
demo_atlas_t *
demo_atlas_create (unsigned int w,
unsigned int h,
unsigned int item_w,
unsigned int item_h_quantum);
demo_atlas_t *
demo_atlas_reference (demo_atlas_t *at);
void
demo_atlas_destroy (demo_atlas_t *at);
void
demo_atlas_alloc (demo_atlas_t *at,
glyphy_rgba_t *data,
unsigned int len,
unsigned int *px,
unsigned int *py);
void
demo_atlas_bind_texture (demo_atlas_t *at);
void
demo_atlas_set_uniforms (demo_atlas_t *at);
#endif /* DEMO_ATLAS_H */
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef DEMO_BUFFER_H
#define DEMO_BUFFER_H
#include "demo-common.h"
#include "demo-font.h"
#include "demo-shader.h"
typedef struct demo_buffer_t demo_buffer_t;
demo_buffer_t *
demo_buffer_create (void);
demo_buffer_t *
demo_buffer_reference (demo_buffer_t *buffer);
void
demo_buffer_destroy (demo_buffer_t *buffer);
void
demo_buffer_clear (demo_buffer_t *buffer);
void
demo_buffer_extents (demo_buffer_t *buffer,
glyphy_extents_t *ink_extents,
glyphy_extents_t *logical_extents);
void
demo_buffer_move_to (demo_buffer_t *buffer,
const glyphy_point_t *p);
void
demo_buffer_current_point (demo_buffer_t *buffer,
glyphy_point_t *p);
void
demo_buffer_add_text (demo_buffer_t *buffer,
const char *utf8,
demo_font_t *font,
double font_size);
void
demo_buffer_draw (demo_buffer_t *buffer);
#endif /* DEMO_BUFFER_H */
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod, Maysum Panju
*/
#ifndef DEMO_COMMON_H
#define DEMO_COMMON_H
#include <glyphy.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <algorithm>
#include <vector>
/* Tailor config for various platforms. */
#ifdef EMSCRIPTEN
/* https://github.com/kripken/emscripten/issues/340 */
# undef HAVE_GLEW
/* WebGL shaders are ES2 */
# define GL_ES_VERSION_2_0 1
#endif
#if defined(__ANDROID__)
# define HAVE_GLES2 1
# define HAVE_GLUT 1
#endif
#ifdef _WIN32
# define HAVE_GL 1
# define HAVE_GLEW 1
#endif
/* Get Glew out of the way. */
#ifdef HAVE_GLEW
# include <GL/glew.h>
#else
# define GLEW_OK 0
static inline int glewInit (void) { return GLEW_OK; }
static inline int glewIsSupported (const char *s)
{ return 0 == strcmp ("GL_VERSION_2_0", s); }
#endif /* HAVE_GLEW */
/* WTF this block?! */
#if defined(HAVE_GLES2)
# include <GLES2/gl2.h>
#elif defined(HAVE_GL)
# ifndef HAVE_GLEW
# define GL_GLEXT_PROTOTYPES 1
# if defined(__APPLE__)
# include <OpenGL/gl.h>
# else
# include <GL/gl.h>
# endif
# endif
# if defined(__APPLE__)
# include <OpenGL/OpenGL.h>
# else
# ifdef HAVE_GLEW
# ifdef _WIN32
# include <GL/wglew.h>
# else
# include <GL/glxew.h>
# endif
# endif
# endif
#endif /* HAVE_GL */
/* Finally, Glut. */
#ifdef HAVE_GLUT
# if defined(__APPLE__)
# include <GLUT/glut.h>
# else
# include <GL/glut.h>
# endif
#endif
/* Logging. */
#ifdef __ANDROID__
# include <android/log.h>
# define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "glyphy-demo", __VA_ARGS__))
# define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "glyphy-demo", __VA_ARGS__))
# define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "glyphy-demo", __VA_ARGS__))
#else /* !__ANDROID__ */
#if 0
# define LOGI(...) ((void) fprintf (stderr, __VA_ARGS__))
# define LOGW(...) ((void) fprintf (stderr, __VA_ARGS__))
# define LOGE(...) ((void) fprintf (stderr, __VA_ARGS__), abort ())
#else
# define LOGI(...) do { } while(false)
# define LOGW(...) do { } while(false)
# define LOGE(...) do { } while(false)
#endif
#endif
#define STRINGIZE1(Src) #Src
#define STRINGIZE(Src) STRINGIZE1(Src)
#define ARRAY_LEN(Array) (sizeof (Array) / sizeof (*Array))
#define MIN_FONT_SIZE 10
#define TOLERANCE (1./2048)
#define gl(name) \
for (GLint ee_, ii_ = 0; \
ii_ < 1; \
(ii_++, \
(ee_ = glGetError()) && \
(reportGLerror (ee_, #name, __LINE__, __FILE__), 0))) \
gl##name
static inline void
reportGLerror(GLint e, const char *api, int line, const char *file)
{
fflush(stdout);
fprintf(stderr, "\nwglGetCurrentDC=%p wglGetCurrentContext=%p\n", wglGetCurrentDC(), wglGetCurrentContext());
fprintf (stderr, "gl%s failed with error %04X on %s:%d\n", api, e, file, line);
fflush (stderr);
exit (1);
}
static inline void
die (const char *msg)
{
fprintf (stderr, "%s\n", msg);
exit (1);
}
template <typename T>
T clamp (T v, T m, T M)
{
return v < m ? m : v > M ? M : v;
}
#if defined(_MSC_VER)
#define DEMO_FUNC __FUNCSIG__
#else
#define DEMO_FUNC __func__
#endif
struct auto_trace_t
{
auto_trace_t (const char *func_) : func (func_)
{ printf ("Enter: %s\n", func); }
~auto_trace_t (void)
{ printf ("Leave: %s\n", func); }
private:
const char * const func;
};
#if 0
#define TRACE() auto_trace_t trace(DEMO_FUNC)
#else
#define TRACE() do { } while(false)
#endif
#endif /* DEMO_COMMON_H */
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef DEMO_FONT_H
#define DEMO_FONT_H
#include "demo-common.h"
#include "demo-atlas.h"
#ifndef _WIN32
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
#ifdef _WIN32
#include <windows.h>
#define DEFAULT_FONT "Calibri"
#undef near
#undef far
#endif
typedef struct {
glyphy_extents_t extents;
double advance;
glyphy_bool_t is_empty; /* has no outline; eg. space; don't draw it */
unsigned int nominal_w;
unsigned int nominal_h;
unsigned int atlas_x;
unsigned int atlas_y;
} glyph_info_t;
typedef struct demo_font_t demo_font_t;
demo_font_t *
demo_font_create (
#ifndef _WIN32
FT_Face face,
#endif
#ifdef _WIN32
HDC hdc,
#endif
demo_atlas_t *atlas);
demo_font_t *
demo_font_reference (demo_font_t *font);
void
demo_font_destroy (demo_font_t *font);
#ifndef _WIN32
FT_Face
#endif
#ifdef _WIN32
HDC
#endif
demo_font_get_face (demo_font_t *font);
demo_atlas_t *
demo_font_get_atlas (demo_font_t *font);
void
demo_font_lookup_glyph (demo_font_t *font,
unsigned int glyph_index,
glyph_info_t *glyph_info);
void
demo_font_print_stats (demo_font_t *font);
#endif /* DEMO_FONT_H */
static const char *demo_fshader_glsl =
"uniform float u_contrast;\n"
"uniform float u_gamma_adjust;\n"
"uniform float u_outline_thickness;\n"
"uniform bool u_outline;\n"
"uniform float u_boldness;\n"
"uniform bool u_debug;\n"
"\n"
"varying vec4 v_glyph;\n"
"\n"
"\n"
"#define SQRT2_2 0.70710678118654757 /* 1 / sqrt(2.) */\n"
"#define SQRT2 1.4142135623730951\n"
"\n"
"struct glyph_info_t {\n"
" ivec2 nominal_size;\n"
" ivec2 atlas_pos;\n"
"};\n"
"\n"
"glyph_info_t\n"
"glyph_info_decode (vec4 v)\n"
"{\n"
" glyph_info_t gi;\n"
" gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;\n"
" gi.atlas_pos = ivec2 (v_glyph.zw) / 256;\n"
" return gi;\n"
"}\n"
"\n"
"\n"
"float\n"
"antialias (float d)\n"
"{\n"
" return smoothstep (-.75, +.75, d);\n"
"}\n"
"\n"
"vec4\n"
"source_over (const vec4 src, const vec4 dst)\n"
"{\n"
" // http://dev.w3.org/fxtf/compositing-1/#porterduffcompositingoperators_srcover\n"
" float alpha = src.a + (dst.a * (1. - src.a));\n"
" return vec4 (((src.rgb * src.a) + (dst.rgb * dst.a * (1. - src.a))) / alpha, alpha);\n"
"}\n"
"\n"
"void\n"
"main()\n"
"{\n"
" vec2 p = v_glyph.xy;\n"
" glyph_info_t gi = glyph_info_decode (v_glyph);\n"
"\n"
" /* isotropic antialiasing */\n"
" vec2 dpdx = dFdx (p);\n"
" vec2 dpdy = dFdy (p);\n"
" float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;\n"
"\n"
" vec4 color = vec4 (0,0,0,1);\n"
"\n"
" float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
" float sdist = gsdist / m * u_contrast;\n"
"\n"
" if (!u_debug) {\n"
" sdist -= u_boldness * 10.;\n"
" if (u_outline)\n"
" sdist = abs (sdist) - u_outline_thickness * .5;\n"
" if (sdist > 1.)\n"
" discard;\n"
" float alpha = antialias (-sdist);\n"
" if (u_gamma_adjust != 1.)\n"
" alpha = pow (alpha, 1./u_gamma_adjust);\n"
" color = vec4 (color.rgb,color.a * alpha);\n"
" } else {\n"
" float gudist = abs (gsdist);\n"
" float debug_color = 0.4;\n"
" // Color the distance field red inside and green outside\n"
" if (!glyphy_isinf (gudist))\n"
" color = source_over (vec4 (debug_color * smoothstep (1., -1., sdist), debug_color * smoothstep (-1., 1., sdist), 0, 1. - gudist), color);\n"
"\n"
" glyphy_arc_list_t arc_list = glyphy_arc_list (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
" // Color the number of endpoints per cell blue\n"
" color = source_over (vec4 (0, 0, debug_color, float(arc_list.num_endpoints) / float(GLYPHY_MAX_NUM_ENDPOINTS)), color);\n"
"\n"
" float pdist = glyphy_point_dist (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
" // Color points yellow\n"
" color = source_over (vec4 (1, 1, 0, smoothstep (.06, .05, pdist)), color);\n"
" }\n"
"\n"
" gl_FragColor = color;\n"
"}\n"
;
/*
* Copyright 2012 Google, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Google Author(s): Behdad Esfahbod
*/
#ifndef DEMO_SHADERS_H
#define DEMO_SHADERS_H
#include "demo-common.h"
#include "demo-font.h"
struct glyph_vertex_t {
/* Position */
GLfloat x;
GLfloat y;
/* Glyph info */
GLfloat g16hi;
GLfloat g16lo;
};
void
demo_shader_add_glyph_vertices (const glyphy_point_t &p,
double font_size,
glyph_info_t *gi,
std::vector<glyph_vertex_t> *vertices,
glyphy_extents_t *extents);
GLuint
demo_shader_create_program (void);
#endif /* DEMO_SHADERS_H */
static const char *demo_vshader_glsl =
"uniform mat4 u_matViewProjection;\n"
"\n"
"attribute vec4 a_glyph_vertex;\n"
"\n"
"varying vec4 v_glyph;\n"
"\n"
"vec4\n"
"glyph_vertex_transcode (vec2 v)\n"
"{\n"
" ivec2 g = ivec2 (v);\n"
" ivec2 corner = ivec2 (mod (v, 2.));\n"
" g /= 2;\n"
" ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));\n"
" return vec4 (corner * nominal_size, g * 4);\n"
"}\n"
"\n"
"void\n"
"main()\n"
"{\n"
" gl_Position = u_matViewProjection * vec4 (a_glyph_vertex.xy, 0, 1);\n"
" v_glyph = glyph_vertex_transcode (a_glyph_vertex.zw);\n"
"}\n"
;
/*
* Copyright (c) 2009, Mozilla Corp
* Copyright (c) 2012, Google, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Based on sample code from the OpenGL(R) ES 2.0 Programming Guide, which carriers
* the following header:
*
* Book: OpenGL(R) ES 2.0 Programming Guide
* Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
* ISBN-10: 0321502795
* ISBN-13: 9780321502797
* Publisher: Addison-Wesley Professional
* URLs: http://safari.informit.com/9780321563835
* http://www.opengles-book.com
*/
/*
* Ported from JavaScript to C by Behdad Esfahbod, 2012.
* Added MultMatrix. Converting from fixed-function OpenGL matrix
* operations to these functions should be as simple as renaming the
* 'gl' prefix to 'm4' and adding the matrix argument to the call.
*
* The C version lives at http://code.google.com/p/matrix4x4-c/
*/
/*
* A simple 4x4 matrix utility implementation
*/
#ifndef MATRIX4x4_H
#define MATRIX4x4_H
/* Copies other matrix into mat */
float *
m4Copy (float *mat, const float *other);
float *
m4Multiply (float *mat, const float *right);
float *
m4MultMatrix (float *mat, const float *left);
float
m4Get (float *mat, unsigned int row, unsigned int col);
float *
m4Scale (float *mat, float sx, float sy, float sz);
float *
m4Translate (float *mat, float tx, float ty, float tz);
float *
m4Rotate (float *mat, float angle, float x, float y, float z);
float *
m4Frustum (float *mat, float left, float right, float bottom, float top, float nearZ, float farZ);
float *
m4Perspective (float *mat, float fovy, float aspect, float nearZ, float farZ);
float *
m4Ortho (float *mat, float left, float right, float bottom, float top, float nearZ, float farZ);
/* In-place inversion */
float *
m4Invert (float *mat);
/* Puts the inverse of other matrix into mat */
float *
m4Inverse (float *mat, const float *other);
/* In-place transpose */
float *
m4Transpose (float *mat);
float *
m4LoadIdentity (float *mat);
float *
m4ApplyToVect (float *mat, float *vec);
#endif
......@@ -42,9 +42,6 @@ typedef std::unordered_map<int,int> IntMap;
#include <graphite_features.hxx>
#endif
// This needs to come after any includes for d2d1.h, otherwise we get lots of errors
#include "glyphy/demo.hxx"
class WinFontInstance;
struct VisualItem;
......@@ -166,7 +163,6 @@ class WinFontInstance : public LogicalFontInstance
public:
explicit WinFontInstance( FontSelectPattern& );
virtual ~WinFontInstance() override;
void setupGLyphy(HDC hDC);
private:
// TODO: also add HFONT??? Watch out for issues with too many active fonts...
......@@ -194,10 +190,6 @@ public:
int GetMinKashidaWidth() const { return mnMinKashidaWidth; }
int GetMinKashidaGlyph() const { return mnMinKashidaGlyph; }
static GLuint mnGLyphyProgram;
demo_atlas_t* mpGLyphyAtlas;
demo_font_t* mpGLyphyFont;
private:
GlyphCache maGlyphCache;
public:
......@@ -212,7 +204,6 @@ private:
std::unordered_map<int, int> maWidthMap;
mutable int mnMinKashidaWidth;
mutable int mnMinKashidaGlyph;
bool mbGLyphySetupCalled;
};
class WinLayout : public SalLayout
......@@ -357,9 +348,6 @@ private:
int mnMinKashidaWidth;
int mnMinKashidaGlyph;
bool mbDisableGlyphInjection;
bool mbUseGLyphy;
bool DrawCachedGlyphsUsingGLyphy(SalGraphics& rGraphics) const;
bool DrawCachedGlyphsUsingTextures(SalGraphics& rGraphics) const;
};
#if ENABLE_GRAPHITE
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment