68 static const char* kVertexShaderSource =
69 "uniform ivec2 uViewportSize;\n"
70 "uniform mat4 uProjectionMatrix;\n"
71 "uniform mat4 uModelviewMatrix;\n"
72 "attribute vec3 aVertex;\n"
73 "attribute vec3 aFontPixelVec;\n"
74 "attribute vec2 aTexCoords;\n"
75 "varying vec2 vTexCoords;\n"
76 "varying vec2 vFontPixelSize;\n"
79 " vTexCoords = aTexCoords;\n"
80 " mat4 pmv = uProjectionMatrix * uModelviewMatrix;\n"
81 " vec4 v0 = pmv * vec4(aVertex, 1.0);\n"
82 " vec4 v1 = pmv * vec4(aVertex + aFontPixelVec, 1.0);\n"
83 " gl_Position = v0;\n"
84 " // Compute the size of a font pixel in screen pixels in X and Y.\n"
85 " vec4 v = (v1 / v1.w) - (v0 / v0.w);\n"
86 " vFontPixelSize = vec2(abs(v.x * float(uViewportSize.x)),\n"
87 " abs(v.y * float(uViewportSize.y)));\n"
90 static const char* kFragmentShaderSource =
92 "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
93 "precision highp float;\n"
95 "precision mediump float;\n"
98 "uniform sampler2D uSdfSampler;\n"
99 "uniform float uSdfPadding;\n"
100 "uniform vec4 uTextColor;\n"
101 "uniform vec4 uOutlineColor;\n"
102 "uniform float uHalfSmoothWidth;\n"
103 "uniform float uOutlineWidth;\n"
104 "varying vec2 vTexCoords;\n"
105 "varying vec2 vFontPixelSize;\n"
107 "void main(void) {\n"
108 " float half_smooth_width = uHalfSmoothWidth;\n"
109 " float outline_width = uOutlineWidth;\n"
111 " // Get the signed distance from the edge in font pixels, centered at\n"
112 " // 0, then convert to screen pixels.\n"
113 " float sdf = texture2D(uSdfSampler, vTexCoords).r;\n"
114 " float dist = uSdfPadding * 2.0 * (sdf - 0.5);\n"
115 " float pixel_scale = mix(vFontPixelSize.x, vFontPixelSize.y, 0.5);\n"
116 " dist *= pixel_scale;\n"
118 " // Ensure the outline blending does not exceed the maximum distance.\n"
119 " float max_dist = uSdfPadding * pixel_scale;\n"
120 " outline_width = min(outline_width, max_dist - half_smooth_width);\n"
122 " // Discard fragments completely outside the smoothed outline.\n"
123 " if (dist >= outline_width + half_smooth_width) {\n"
127 " // Set to blended outline color.\n"
128 " float outline_min = outline_width - half_smooth_width;\n"
129 " float outline_max = outline_width + half_smooth_width;\n"
130 " float d1 = smoothstep(outline_min, outline_max, dist);\n"
131 " color = (1.0 - smoothstep(outline_min, outline_max, dist)) *\n"
134 " // Blend in text color.\n"
135 " float interior_bias = 0.2;\n"
136 " float interior_min = -half_smooth_width + interior_bias;\n"
137 " float interior_max = half_smooth_width + interior_bias;\n"
138 " float d2 = smoothstep(interior_min, interior_max, dist);\n"
139 " color = mix(uTextColor, color,\n"
140 " smoothstep(interior_min, interior_max, dist));\n"
141 " gl_FragColor = vec4(color.rgb * color.a, color.a);\n"
157 static const math::Vector3f ComputeFontPixelVec(
158 const Font& font,
const Layout& layout,
size_t glyph_index) {
159 const Layout::Glyph& glyph = layout.GetGlyph(glyph_index);
160 const Font::GlyphGrid& grid = font.GetGlyphGrid(glyph.glyph_index);
161 math::Vector3f vec(math::Vector3f::Zero());
163 const size_t width = grid.pixels.GetWidth();
164 const size_t height = grid.pixels.GetHeight();
165 if (width && height) {
166 const float inv_width = 1.0f /
static_cast<float>(
width);
167 const float inv_height = 1.0f /
static_cast<float>(height);
168 const math::Point3f& lower_left = glyph.quad.points[0];
169 const math::Point3f& lower_right = glyph.quad.points[1];
170 const math::Point3f& upper_left = glyph.quad.points[3];
171 const math::Vector3f v_right = (lower_right - lower_left) * inv_width;
172 const math::Vector3f v_up = (upper_left - lower_left) * inv_height;
173 vec = v_right + v_up;
192 :
Builder(font_image, shader_manager, allocator) {}
219 reg->IncludeGlobalRegistry();
232 "Half of edge smoothing width in pixels"));
237 std::string* vertex_source,
238 std::string* fragment_source) {
239 *id_string =
"Outline Text Shader";
240 *vertex_source = kVertexShaderSource;
241 *fragment_source = kFragmentShaderSource;
250 const float sdf_padding =
256 "uSdfPadding", sdf_padding));
260 "uTextColor", math::Point4f(1.f, 1.f, 1.f, 1.f)));
262 "uOutlineColor", math::Point4f(0.f, 0.f, 0.f, 0.f)));
278 .Bind(v.position,
"aVertex")
279 .
Bind(v.texture_coords,
"aTexCoords")
280 .
Bind(v.font_pixel_vec,
"aFontPixelVec")
287 size_t* num_vertices) {
290 *vertex_size =
sizeof(Vertex);
291 *num_vertices = 4 * num_glyphs;
294 vertex_data.resize(
sizeof(Vertex) * (*num_vertices));
295 Vertex* vertices =
reinterpret_cast<Vertex*
>(&vertex_data[0]);
296 math::Point3f positions[4];
300 for (
size_t i = 0; i < num_glyphs; ++i) {
302 const math::Vector3f font_pixel_vec = ComputeFontPixelVec(font, layout, i);
303 for (
int j = 0; j < 4; ++j)
304 vertices[4 * i + j] =
305 Vertex(positions[j], texture_coords[j], font_pixel_vec);
bool IsInvalidReference(const T &value)
IsInvalidReference() returns true if a passed const reference of type T has an address of InvalidRefe...
kShortTerm is used for objects that are very transient in nature, such as scratch memory used to comp...
void StoreGlyphVertices(const Layout &layout, size_t glyph_index, math::Point3f positions[4], math::Point2f texture_coords[4])
Fills in the position and texture_coords for the 4 vertices of the indexed Layout glyph quad...
size_t GetSdfPadding() const
Returns the padding value used when generating SDF glyphs from the font.
const FontPtr GetFont() const
Returns the Font from the FontImage. This may be a NULL pointer.
bool UpdateFontImageTextureUniform(size_t index, gfx::Node *node)
Modifies the indexed Texture uniform in the node if necessary to contain the current FontImage image...
bool SetTextColor(const math::VectorBase4f &color)
const base::AllocatorPtr & GetAllocator()
Returns the Allocator passed to the constructor.
void UpdateUniforms(const gfx::ShaderInputRegistryPtr ®istry, gfx::Node *node) override
Adds or updates uniforms for the shaders in the node.
bool SetOutlineWidth(float width)
const AllocatorPtr & GetAllocatorForLifetime(AllocationLifetime lifetime) const
Convenience function that returns the Allocator to use to allocate an object with a specific lifetime...
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
OutlineBuilder(const FontImagePtr &font_image, const gfxutils::ShaderManagerPtr &shader_manager, const base::AllocatorPtr &allocator)
OutlineBuilder functions.
const gfx::ShaderInputRegistryPtr GetShaderInputRegistry() override
Required Builder functions.
~OutlineBuilder() override
The destructor is protected because all base::Referent classes must have protected or private destruc...
void GetShaderStrings(std::string *id_string, std::string *vertex_source, std::string *fragment_source) override
Returns the strings needed for shader definition.
bool SetOutlineColor(const math::VectorBase4f &color)
const gfx::NodePtr & GetNode() const
Returns the Node set up by the last successful call to Build().
#define DCHECK_GE(val1, val2)
size_t GetGlyphCount() const
Returns the number of glyphs added to the layout.
BufferToAttributeBinder is a simple interface to insert a set of Attributes containing BufferObjectEl...
Copyright 2016 Google Inc.
A Layout instance specifies how glyphs are arranged to form text.
BufferToAttributeBinder & Bind(const FieldType &field, const std::string &attribute_name)
base::AllocVector< char > BuildVertexData(const Layout &layout, size_t *vertex_size, size_t *num_vertices) override
Returns a vector of data that represents vertex data, the size of a vertex, the number of vertices...
bool SetHalfSmoothWidth(float width)
void BindAttributes(const gfx::AttributeArrayPtr &attr_array, const gfx::BufferObjectPtr &buffer_object) override
Binds attributes for the Builder's shader program.
const gfx::TexturePtr GetFontImageTexture()
Returns a Texture that contains the FontImage image.
Builder is an abstract base class for building graphics objects used to render text.
A Node instance represents a node in a scene graph.
A SharedPtr is a smart shared pointer to an instance of some class that implements reference counting...
Font is a base class for implementation-specific representations of fonts.
void Apply(const gfx::ShaderInputRegistryPtr ®, const gfx::AttributeArrayPtr &aa, const gfx::BufferObjectPtr &bo)
This class can be used in place of std::vector to allow an Ion Allocator to be used for memory alloca...
bool SetSdfPadding(float padding)
These convenience functions can be used to modify uniform values in the built Node returned by GetNod...
const FontImagePtr & GetFontImage() const
Returns the FontImage passed to the constructor.