You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guides/custom_fonts.md
+24-7Lines changed: 24 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,12 +2,12 @@
2
2
3
3
Scenic ships standard with support for the [Roboto](https://fonts.google.com/specimen/Roboto) and [Roboto_Mono](https://fonts.google.com/specimen/Roboto+Mono) fonts. The [Roboto_Slab](https://fonts.google.com/specimen/Roboto+Slab) font is no longer standard in Scenic.
4
4
5
-
You can add the RobotoSlab font, and most any other TrueType font you want to use into Scenic.
5
+
You can, however, add the RobotoSlab font, and most any other TrueType font you want to use into Scenic.
6
6
7
7
To do this you will need do the following steps.
8
8
9
9
1. Download the font you want to use and add it to the static files of your `priv/` folder in your application. Please be aware of font licenses and make good choices.
10
-
2. Use the truetype_metrics hex package to generate a `*.metrics` file, which you also add to your `priv/` folder. This tool will also change the name of your font so that a hash of the data is included in the file name.
10
+
2. Use the [truetype_metrics](https://hex.pm/packages/truetype_metrics) hex package to generate a `*.metrics` file, which you also add to your `priv/` folder. This tool will also change the name of your font so that a hash of the data is included in the file name.
11
11
3. Load the `*.metrics` file into the `Scenic.Cache.Static.FontMetrics` cache.
12
12
4. refer to the font by the key to the metrics file in the graph where you want to use it.
13
13
@@ -28,9 +28,9 @@ priv/
28
28
29
29
## Generate the `\*.metrics` file
30
30
31
-
Use the truetype_metrics tool to generate a font metrics file. This tool is not included in Scenic because this code is complicated (don't get me started on the TrueType format) and only needs to be run once when you set it up.
31
+
Use the [truetype_metrics](https://hex.pm/packages/truetype_metrics) tool to generate a font metrics file. This tool is not included in Scenic because this code is complicated (don't get me started on the TrueType format) and only needs to be used once when you set up your project.
32
32
33
-
This tool will do two things. It will create a .metrics file and decorate the name of the font itself with a hash of its contents.
33
+
This tool will do two things. It will create a `\*.metrics` file and decorate the name of the font itself with a hash of its contents.
34
34
35
35
You may need to install the tool as an archive first
36
36
@@ -56,24 +56,41 @@ priv/
56
56
RobotoSlab-Regular.ttf.metrics
57
57
```
58
58
59
-
Read the truetype_metrics documentation to learn how to recurse font folders, control the font name decoration and force the file to be re-generated.
59
+
Read the [truetype_metrics](https://hex.pm/packages/truetype_metrics) documentation to learn how to recurse font folders, control the font name decoration and force the file to be re-generated.
60
60
61
-
## Load the `\*.metrics` file into the cache
61
+
## Load the `\*.metrics` file and the font into the cache
62
62
63
-
In your scene, you need to make load the `\*.metrics` file into the `Scenic.Cache.Static.FontMetrics` cache.
63
+
In your scene, you need to make load both the `\*.metrics` file into the `Scenic.Cache.Static.FontMetrics` cache and the font itself into the `Scenic.Cache.Static.Font` cache.
# no need to put the graph into state as we won't be using it again
79
+
{:ok, nil, push:@graph}
80
+
end
67
81
```
68
82
69
83
Note that if you use this font everywhere, you may want to load it once during app startup with the `:global` scope. Then you can just refer to it without having to load it in every scene.
Finally, you use the key to refer to the font metrics in the graph. The font itself will be loaded and used automatically as needed. The metrics file already contains the hash of the font itself.
Notice that the graph is modified multiple times in the pipeline. The `push_graph/1` function is relatively heavy when the graph references other scenes. The recommended pattern is to make multiple changes to the graph and then push once at the end.
88
+
Notice that the graph is modified multiple times in the pipeline.
Notice that the graph is modified multiple times in the pipeline. The `push_graph/1` function is relatively heavy when the graph references other scenes. The recommended pattern is to make multiple changes to the graph and then push once at the end.
97
+
Notice that the graph is modified multiple times in the pipeline.
99
98
100
99
The last parameter to `Graph.modify/3` is a pointer to a function that receives a primitive and returns the the new primitive that should be inserted in its place.
@@ -85,14 +84,12 @@ build and push your first graph, the user will see a blank space or screen until
85
84
you are ready.
86
85
87
86
def init( _scene_args, opts ) do
88
-
push_graph( @graph )
89
-
90
87
state = %{
91
88
graph: @graph,
92
89
viewport: opts[:viewport]
93
90
}
94
91
95
-
{:ok, state}
92
+
{:ok, state, push: @graph}
96
93
end
97
94
98
95
The first argument, `scene_args`, is any term that you pass to your scene when
@@ -134,51 +131,40 @@ option | description
134
131
135
132
## Pushing a Graph
136
133
137
-
`push_graph/1` is a "magic" function. Magic functions embody knowledge of the
138
-
system outside of the data passed into them and are not purely "functional" in
139
-
the programming sense. I am generally against using magic functions. However,
140
-
after much thought and experimentation, I landed on this one bit of magic to
141
-
accomplish a difficult job.
142
-
143
-
> `push_graph/1` is a private function that is injected into your scene by the
144
-
> `use Scenic.Scene` macro. Your scene will not work without it.
145
-
146
-
In a nutshell, `push_graph/1` does two jobs.
147
-
148
-
First, it triggers the [life-cycle](scene_lifecycle.html) of any components the
149
-
graph references. This means that component processes may start or stop when you
150
-
push a graph. This will only happen if you change components used in the graph.
134
+
Previous to v0.10, the way to push a graph to the ViewPort was the magic `push_graph/1` function, This has been deprecated in favor of a more functional return option. `push_graph/1` was also interfering with the newer OTP 21+ continue callbacks and timeouts and such. Since this is only a deprecation `push_graph/1` will continue to work, but will log a warning when used. `push_graph/1` will be removed in a future release.
151
135
152
-
Second, it prepares the graph for use by the [Drivers](overview_driver.html) and
153
-
the input path of the [ViewPort](overview_viewport.html). This mostly involves
154
-
stripping internal data and caching the resulting term in an
155
-
[ets](https://elixirschool.com/en/lessons/specifics/ets/) table so that it can
156
-
be used very quickly, on demand, by those systems.
136
+
The new, better way to push a graph is via a {:push, graph} option when you return from any scene callback.
157
137
158
-
`push_graph/1` returns the original graph passed in to it. This is so you can
159
-
hang the call off the end of a pipe chain that transforms the graph. This isn't
160
-
really necessary, but I like it as it visually indicates that the graph was
More on `Graph.modify` in the [input](#user-input) and [events](#events)
168
-
sections below. Also see the [Graph Overview](overview_graph.html) page.
149
+
Almost all (except terminate...) of the callbacks accept a `{:push, graph}` option. Replacing the call of `push_graph(graph)` within a callback function depends slightly on the context in which it is used.
169
150
170
-
As you can guess, `push_graph/1` is relatively heavy since it scans every node
171
-
in your graph every time you call it. You should only call it once per input or
172
-
event that you handle.
151
+
* in `init/2`:
152
+
*`{:ok, state, [push: graph]}`
153
+
* in `filter_event/3`:
154
+
*`{:halt, state, [push: graph]}`
155
+
*`{:cont, event, state, [push: graph]}`
156
+
* in `handle_cast/2`:
157
+
*`{:noreply, state, [push: graph]}`
158
+
* in `handle_info/2`:
159
+
*`{:noreply, state, [push: graph]}`
160
+
* in `handle_call/3`:
161
+
*`{:reply, reply, state, [push: graph]}`
162
+
*`{:noreply, state, [push: graph]}`
163
+
* in `handle_continue/3`:
164
+
*`{:noreply, state, [push: graph]}`
173
165
174
-
> A best practice is to make multiple modifications to a graph and then call
175
-
> `push_graph/1` at the end.
166
+
See the [documentation for scene callbacks](Scenic.Scene.html#callbacks) for more information.
176
167
177
-
graph = graph
178
-
|> Graph.modify(:text, &text(&1, "I've been modified") )
0 commit comments