1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Xgridfit</title>
<link rel="stylesheet" href="oeg.css" media="screen" type="text/css" />
<link rel="stylesheet" href="parchment.css" media="screen"
type="text/css" title="parchment" />
<link rel="alternate stylesheet" href="legible.css" media="screen"
type="text/css" title="legible" />
<style type="text/css" media="print"> @import "oeg.print.css"; </style>
<meta name="AUTHOR" content="Peter S. Baker" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<div id="jumplist">
<a href="http://sourceforge.net"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=159705&type=4" width="125" height="37" border="0" alt="SourceForge.net Logo" /></a>
<a href="http://xgridfit.sourceforge.net/">Home Page</a>
<a href="http://sourceforge.net/projects/xgridfit">Project Page</a>
<a href="http://sourceforge.net/project/showfiles.php?group_id=159705">Download</a>
<a href="http://xgridfit.cvs.sourceforge.net/xgridfit/xgridfit/">CVS repository</a>
<hr/>
<a href="#set-vectors"><set-vectors></a>
<a href="#set-vectors"><with-vectors></a>
<a href="#set-projection-vector"><set-projection-vector></a>
<a href="#set-projection-vector"><with-projection-vector></a>
<a href="#set-freedom-vector"><set-freedom-vector></a>
<a href="#set-freedom-vector"><with-freedom-vector></a>
<a href="#set-dual-projection-vector"><set-dual-projection-vector></a>
<a href="#store-projection-vector"><store-projection-vector></a>
<a href="#store-projection-vector"><store-freedom-vector></a>
</div>
<div id="content">
<h1>Vectors</h1>
<p>A vector is a direction represented by a line. The TrueType engine stores a
vector as an x,y coordinate pair--that is, as one end-point of a line. The other
end-point of the line that defines a vector is always at coordinate 0,0.
The actual location of the line is not so important, however, as the direction
the line defines. Vectors stored by the TrueType engine determine how
measurements are made and how points are moved.</p>
<p>The TrueType engine maintains three vectors:</p>
<ul>
<li><b>The freedom vector.</b> Almost all the instructions that move points
move them along (i.e. parallel to) the freedom vector (an important exception is
<move-point-to-intersection>).</li>
<li><b>The projection vector.</b> Almost all instructions that measure
distance (this includes almost all instructions that move points) do so
along the projection vector.</li>
<li><b>The dual projection vector.</b> This is usually the same as the
projection vector, but when it is different it is used by the
<interpolate>, <measure-distance>, <mdrp> and
<mirp> instructions--also by <move> when a "relative-to"
point is present.</li>
</ul>
<p>Most of the time the three vectors all point in the same direction, with
the result that it is easy to visualize how instructions that move points
work. For example, this code</p>
<pre>
<with-vectors axis="x">
<move distance="left-sidebearing">
<reference>
<point num="a"/>
</reference>
<point num="b"/>
</move>
</with-vectors>
</pre>
<p>moves point <b>b</b> along the horizontal freedom vector until
it is positioned the rounded distance
"left-sidebearing" from point <b>a</b> (the character origin at 0,0),
as measured along the horizontal projection
vector. When measuring the distance and
moving the point, the TrueType engine treats both <b>a</b> and <b>b</b> as if
they were arrayed in a single dimension, and the y axis did not
exist. These images illustrate the effect of the move:</p>
<table>
<tr><td>
<img alt="before move of point b" src="x-vec-a.gif"/>
</td>
<td>
<img alt="after move of point b" src="x-vec-b.gif"/>
</td>
</tr></table>
<p>The freedom and projection vectors need not match. In the leftmost
image below, the glyph program has moved point <b>a</b>, which defines
the top of a serif, up to the nearest gridline. As a result point
<b>b</b> is too close to <b>a</b> and ought to be moved up by the same
amount. But
moving it straight up would alter the slope of the diagonal line whose
bottom point it defines. The solution is to set the freedom vector to
be parallel to the diagonal so that point <b>b</b> moves along that
line without distorting it. This code will do it:</p>
<pre>
<with-projection-vector axis="y">
<with-freedom-vector to-line="parallel">
<line>
<point num="b"/>
<point num="c"/>
</line>
<shift>
<reference>
<point num="a"/>
</reference>
<point num="b"/>
</shift>
</with-freedom-vector>
</with-projection-vector>
</pre>
<p>The middle image shows the result of the move, and the last image shows the
same area of the glyph after execution of <interpolate-untouched-points>.</p>
<table>
<tr><td>
<img alt="before move of point b" src="A1.gif"/>
</td>
<td>
<img alt="after move of point b" src="A2.gif"/>
</td>
<td>
<img alt="after move of point b" src="A3.gif"/>
</td>
</tr></table>
<p>Notice how the curve that joins the diagonal to the serif is preserved
even at 16 pixels-per-em. An anti-aliasing program can give an impression
of this curve, as in the image below, which is enlarged 8x.</p>
<table>
<tr><td>
<img alt="before move of point b" src="A4.gif"/>
</td>
</tr></table>
<p>A vector has a direction, though this is rarely significant.
When the vector is set to the y axis, it points up; when set to the
x axis, it points right. When set to a line, it points from the
second point in the <line> element to the first: imagine
an arrow on the first point.</p>
<h2 id="vect-inst">Instructions that set vectors</h2>
<p>Instructions that begin with <tt>set</tt> set one or two vectors,
and these remain as set until another vector-setting instruction is
encountered. Instructions that begin with <tt>with</tt> set vectors
that apply only to the instructions contained within the <tt>with</tt>
element.</p>
<p>Instructions that set the projection vector, freedom vector, or
both may do so in any of four ways:</p>
<ul>
<li>by including an <tt>axis</tt> attribute whose value is <tt>x</tt>
or <tt>y</tt>.</li>
<li>by including a <line> element as the child of a <tt>set</tt>
instruction or the first child of a <tt>with</tt> instruction. You
may also include the <tt>to-line</tt> attribute on the <tt>set</tt>
or <tt>with</tt> element to indicate whether the vector should be
<tt>parallel</tt> or <tt>orthogonal</tt> to the line (the default is
<tt>parallel</tt>).</li>
<li>by including the attributes <tt>x-component</tt> and <tt>y-component</tt>,
giving the x and y components of the point that defines the vector. The
sum of the squares of these numbers must be <tt>1v</tt> (or 16384 if
integers are used). It would be difficult to calculate these
coordinates on the fly, so this method is chiefly useful for restoring
saved vectors.</li>
<li>by doing none of these things, in which case a <tt>set</tt>
instruction attempts to retrieve the required vector(s) from the
stack while a <tt>with</tt> element only saves the current vector(s),
executes the instructions it contains, and then restores the vector(s).</li>
</ul>
<h3 id="set-vectors"><set-vectors><br/><with-vectors></h3>
<p>Sets both the projection vector and the freedom vector to
the same value. They can be set to "x" or "y" via the
<tt>axis</tt> attribute; to a line by including a line element
as the content of the <set-vectors> element or the first
child of the <with-vectors> element; or by passing
"raw" values via the <tt>x-component</tt> and <tt>y-component</tt>
attributes.</p>
<p>Xgridfit looks first for an <tt>axis</tt> attribute, next for
a <line>, and finally for <tt>x-component</tt> and <tt>y-component</tt>
attributes (neither is used unless both are present). If
it finds none of these, Xgridfit prints a warning and
attempts to find the values it needs on the stack.</p>
<p>The "raw" values passed in via <tt>x-component</tt> and <tt>y-component</tt>
are constrained in ways that make them
difficult to calculate, at least in a TrueType program,
but the <tt>x-component/y-component</tt> method is useful to
restore values that have been saved via <store-projection-vector>
or <store-freedom-vector>. For example, to
copy one vector to another, you can do this:</p>
<pre>
<variable name="x-comp"/>
<variable name="y-comp"/>
<store-freedom-vector x-component="x-comp" y-component="y-comp"/>
<set-projection-vector x-component="x-comp" y-component="y-comp"/>
</pre>
<p>But because of the way these instructions can leave values on
the stack and take them from the stack again, this is easier and
more efficient:</p>
<pre>
<store-freedom-vector/>
<set-projection-vector/>
</pre>
<p>When setting vectors to a line, one or both points in
the line can be in the twilight zone. You can include
a <tt>zone</tt> attribute in the <line> element or one in
either or both <point> elements. Include a <tt>zone</tt>
attribute in the <line> element if both points are in
the twilight zone. This is the same as including an
attribute <tt>zone="twilight"</tt> in both points. If only one
point is in the twilight zone, include the <tt>zone</tt>
attribute for that point.</p>
<h4>Attributes</h4>
<dl>
<dt>axis</dt>
<dd>The axis to which the vectors should be set. Permitted values
are <tt>x</tt> and <tt>y</tt>.</dd>
<dt>to-line</dt>
<dd>Whether the vectors should be parallel or orthogonal
(perpendicular) to the line being used to set the
vector. The default value is <tt>parallel.</tt></dd>
<dt>x-component</dt>
<dd>The x component of the vector to set. This has no
effect unless the <tt>y-component</tt> attribute is included
as well.</dd>
<dt>y-component</dt>
<dd>The y component of the vector to set. This has no
effect unless the <tt>x-component</tt> attribute is included
as well.</dd>
</dl>
<h3 id="set-projection-vector"><set-projection-vector><br/><with-projection-vector></h3>
<p>Just like <set-vectors>, but sets only the projection vector.</p>
<h3 id="set-freedom-vector"><set-freedom-vector><br/><with-freedom-vector></h3>
<p>Just like <set-vectors>, but sets only the freedom vector.</p>
<h3 id="set-dual-projection-vector"><set-dual-projection-vector></h3>
<p>Like <set-projection-vector>, but the dual projection vector
can be set only from a line, and it uses the original
positions in the outline of the points that constitute the
line rather than their current positions (assuming they have
moved).</p>
<p>The dual projection vector is not used by every instruction:
just by <interpolate>, <get-coordinate>, <measure-distance>,
<mirp>, <mdrp>, and <move> (only when a
"relative-to" point is present). This vector lasts only until
a new projection vector is set; then it gets canceled.</p>
<p>One or both points in the line may be in the twilight zone.
See the explanation for <set-vectors>.</p>
<h2>Instructions that store vectors</h2>
<h3 id="store-projection-vector"><store-projection-vector><br/><store-freedom-vector></h3>
<p>These instructions store a vector as two numbers, an
x-component and a
y-component. The <tt>x-component</tt> and <tt>y-component</tt>
attributes, if given, must be identifiers for variables:</p>
<pre>
<store-projection-vector x-component="vx" y-component="vy"/>
</pre>
<p>
If variables are not given, a warning is printed and the
values are left on the stack, where they will be picked
up correctly by a following <tt>set</tt> instruction.
For example, this code sets the projection vector to be the
same as the freedom vector:</p>
<pre>
<store-freedom-vector/>
<set-projection-vector/>
</pre>
<p>Note that a <tt>with</tt> block will not pick up the components
of a vector from the stack.</p>
<h4>Attributes</h4>
<dl>
<dt>x-component</dt>
<dd>The x-component of the vector. Both the <tt>x-component</tt>
and the <tt>y-component</tt> must be present if either is present;
otherwise the one that is present is ignored, and the two components
of the vector are left on the stack.</dd>
<dt>y-component</dt>
<dd>The y-component of the vector.</dd>
</dl>
</div>
</body>
</html>
|