truetype font ARGS_ARE_XY_VALUES meaning? - truetype

In the glyf table, if a glyph is a composite glyph, I don't understand what it means if the flag ARGS_ARE_XY_VALUES is not set. The msdn docs say
the first point number indicates the point that is to be matched to the new glyph. The second number indicates the new glyph’s “matched” point. Once a glyph is added, its point numbers begin directly after the last glyphs (endpoint of first glyph + 1).
But I have NO idea what it means:
What is a "point number"? Is it an index into the glyph's points?
What does "matched to the new glyph" mean?

What is a "point number"? Is it an index into the glyph's points?
Yes. It’s an index into the array of pairs of coordinates that make up the glyph’s outline (as defined in the glyph’s contour data).
What does "matched to the new glyph" mean?
It means that the new component glyph of that composite/compound glyph is to be positioned so that the coordinates of its ‘match point’ are equal to those of the ‘match point’ of the base component glyph. In other words: so that the indicated points for the two components match. This is repeated for each new component glyph, with the point numbers/indices of the already matched components being treated as if it were a single, base component glyph.

Apple's TrueType spec is a bit clearer about the meaning of this flag. It says that if the ARGS_ARE_XY_VALUES flag is not set that:
1st short contains the index of matching point in compound being constructed
2nd short contains index of matching point in component
Source: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html
In other words, let m be the first short and n be the second, then the coordinates of point n of the new component should have the same coordinates as point m of the so far constructed compound glyph.

Related

How to correctly understand TrueType cmap's subtable Format 4?

The following is the information, which the TrueType font format documentation provides with regards to the fields of "Format 4: Segment mapping to delta values" subtable format, which may be used in cmap font table (the one used for mapping character codes to glyph indeces):
Type Name Description
1. uint16 format Format number is set to 4.
2. uint16 length This is the length in bytes of the subtable.
3. uint16 language For requirements on use of the language field, see “Use of the language field in 'cmap' subtables” in this document.
4. uint16 segCountX2 2 × segCount.
5. uint16 searchRange 2 × (2**floor(log2(segCount)))
6. uint16 entrySelector log2(searchRange/2)
7. uint16 rangeShift 2 × segCount - searchRange
8. uint16 endCode[segCount] End characterCode for each segment, last=0xFFFF.
9. uint16 reservedPad Set to 0.
10. uint16 startCode[segCount] Start character code for each segment.
11. int16 idDelta[segCount] Delta for all character codes in segment.
12. uint16 idRangeOffset[segCount] Offsets into glyphIdArray or 0
13. uint16 glyphIdArray[ ] Glyph index array (arbitrary length)
(Note: I numbered the fields as to allow referencing them)
Most fields, such as 1. format, 2. length,3. language,9. reservedPad` are trivial basic info and understood.
Other fields 4. segCountX2, 5. searchRange, 6 .entrySelector, 7. rangeShift I see as some odd way to have a precomputed values, but basically being only a redundant way to store the number of segments segCount (implicitly). Also those fields I have no major headache understanding.
Lastly there remain the fields that represent arrays. Per each segment there is a field 8. endCode, 10. stadCode, 11. idDelta and 12. idRangeOffset and there might/might not be even a field 13. glyphIdArray. Those are the fields I still struggle to interprete correctly and which this question is about.
To allow for a most helpful answer allow me to sketch quickly my take on those fields:
Working basically segment for segment, each segment maps characters codes from startCode to endCode to the indexes of the fonts glyphs (reflecting the order they appear in the glyf table).
having the character code as input
having the glyph index as output
segment is determined by iterating through them checking that the input value is inside the range of startCode to endCode.
with the segment found thus, the fields respective fields idRangeOffset and idDelta are determined as well.
idRangeOffset conveys a special meaning
case A) idRangeOffset being set to special value 0 means that the ouput can be
calculated from the input value (character code) and the idDelta. (I think it is either glyphId = inputCharCode + idDelta or glyphId = inputCharCode - idDelta )
case B) idRangeOffset being not 0 something different happens, which is part of what I seek an answer about here.
With respect to case B) the documentation states:
If the idRangeOffset value for the segment is not 0, the mapping of
character codes relies on glyphIdArray. The character code offset from
startCode is added to the idRangeOffset value. This sum is used as an
offset from the current location within idRangeOffset itself to index
out the correct glyphIdArray value. This obscure indexing trick works
because glyphIdArray immediately follows idRangeOffset in the font
file. The C expression that yields the glyph index is:
glyphId = *(idRangeOffset[i]/2
+ (c - startCode[i])
+ &idRangeOffset[i])
which I think provides a way to map a continuous input range (hence "segment") to a list of values stored in the field glyphIdArray, possibly as a way to provide output values that cannot be computed via idDelta, for being unordered/non-consecutive. This at least is my read on that what was described as "obscure" in the documentation.
Because glyphIdArray[] follows idRangeOffset[] in the TrueType file, the code segment in question
glyphId = *(&idRangeOffset[i]
+ idRangeOffset[i]/2
+ c - startCode[i])
points to the memory address of the desired position in glyphIdArray[]. To elaborate on why:
&idRangeOffset[i] points to the memory address of idRangeOffset[i]
moving forward idRangeOffset[i] bytes (or idRangeOffset[i]/2 uint16's) brings you to the relevant section of glyphIdArray[]
c - startCode[i] is the position in glyphIdArray[] that contains the desired ID value
From here, in the event that this ID is not zero, you will add idDelta[i] to obtain the glyph number corresponding to c.
It is important to point out *(&idRangeOffset[i] + idRangeOffset[i]/2 + (c - startCode[i])) is really pseudocode: you don't want a value stored in your program's memory, but rather the memory address in the file.
In a more modern language without pointers, the above code segment translates to:
glyphIndexArray[i - segCount + idRangeOffset[i]/2 + (c - startCode[i])]
The &idRangeOffset[i] in the original code segment has been replaced by i - segCount (where segCount = segCountX2/2). This is because the range offset (idRangeOffset[i]/2) is relative to the memory address &idRangeOffset[i].

Original domain in periodic triangulation with CGAL

I have some questions regarding the periodic triangulation in CGAL.
1) According to my understanding of the manual examples (http://doc.cgal.org/latest/Periodic_2_triangulation_2/examples.html) and the reference manual if we don't use Iso_rectangle in constructing triangles, (0,0,1,1) is chosen as the default value, am I right?
2) What is the meaning of this statement from manual? "input point is required to be an element of the half-open square representing the original domain"
3) "Another effect is that when the algorithm switches from 9-sheeted covering to 1-sheeted covering the Vertex_handles and Face_handles referencing deleted items becomes invalid", Does this mean that If I have vertex circulator in code, those adjacent vertices that are in periodic boxes, are neglected and not displayed in the output?
1) yes
Triangulation_2 (const Iso_rectangle &domain=Iso_rectangle(0, 0, 1, 1), const Geom_traits &traits=Geom_traits())
http://doc.cgal.org/latest/Periodic_2_triangulation_2/classCGAL_1_1Periodic__2__triangulation__2.html#a1e9c60f7c9844a33edff96b95aeb6c85
2) all insert functions have a precondition ensuring that input points are in the half-open square defined in Secrtion 1 of the user manual
http://doc.cgal.org/latest/Periodic_2_triangulation_2/index.html#title0
3) I am not sure that I understand what you mean by "neglected".
When the triangulation is in 1-sheeted covering mode, each vertex/face is stored only once, without copy, so the iterators/circulators simply traverse the triangulation directly in the flat torus. For a vertex circulator, you get all adjacent vertices.

What does PACK8/16/32 mean in VkFormat names?

I'm trying to understand the names of the items in the VkFormat enum, and so far I think I get all the structure of the names of all of the (non-block) formats, but I can't figure out what it means when they have a suffix of PACK8, PACK16, PACK32. If I add up the channel sizes, they always add up to 8, 16, or 32, nothing irregular, so I don't understand what it would mean to bit-pack these values, since they seem to be 100% efficient, using all their bits.
As usual, the documentation is not very helpful, just saying the format is packed without saying what that means.
The PACK fields mean exactly what the specification says they mean:
whole texels or attributes are stored in a single data element, rather than individual components occupying a single data element
Though if you find that too confusing, you could just look at the actual format descriptions. Vulkan goes into excruciating detail about them, to the point of needless repetition.
The difference between VK_FORMAT_B8G8R8A8_RGB and VK_FORMAT_B8G8R8A8_RGB_PACK32 is the same difference between a uint8_t[4] and a uint32_t. One is an array ("individual components"), while the other is a single value ("single data element") made up of smaller values.
If you have a uint8_t color[4] array, which stores B8G8R8A8, then color[0] stores the blue component. The order of the components in the array is defined by the order of the components in the format's name.
If you have a uint32_t color value, which stores B8G8R8A8, then (color & 0xFF000000) >> 24 will retrieve the blue component. The highest byte is the first, followed by the next highest and so forth.
The reason the packed-vs-not-packed distinction matters is because of endian issues. Arrays of bytes don't have endian issues. But values packed into 16 or 32-bits do have endian issues. The endian of the packed formats is always assumed to be the native endian of the host.

How to detect/handle touch events on curved regions?

I'm starting on a native iPad app (we can assume iOS 4.3+ if necessary) where I need to have a series of curved regions that bump up against each other.
I'd love some advice about the best way to handle this.
One thought I had was to use a WebView and just have a JPG and an HTML image map but I'd really prefer to use some kind of native UI element that supports curves.
Any recommendations?
We had a problem something like this. To resolve it, we created a black and white mask in Adobe Illustrator. You'll need to do this for each and every distinct region that you want.
Next, we exported this file. I can't remember the file export option, but basically you get a text file that has a load of path data that includes lines, bezier curves, etc.
We then took this file and wrote an importer that parsed it and created a CGPath.
The final stage is the easy bit. You get your touch point from UITouch and do a CGPathContainsPoint call.
Here's some pseudo code for this:
Skip lines until we get to one with "1 XR". That's the
indication of something meaningful in the subsequent line.
Split the line into an array of components using a separator of " ".
The last component of the line is the action. If it's "m" it's a path move, if it's "C", it's a bezier curve, and if it's "L" it's a line.
If it's a "Y" or a "V" then you need to get the previous line's components and parse as follows:
(a) Component count includes action, so we need to reduce this. E.g. 274.5600 463.6800 m
(b) If this line has four coordinates and the previous one has two, then it's a point node to a bezier node. Figure your bezier curve points as follows:
cp1x = previous line's components object at index 0
cp1y = previous line's components object at index 1
cp2x = this line's components object at index 0
cp2y = this line's components object at index 1
x = this line's components object at index 2
y = this line's components object at index 3
(c) Otherwise if this line has four coordinates and the previous line has four or six coordinates, figure as follows:
cp1x = this line's components object at index 0
cp1y = this line's components object at index 1
cp2x = this line's components object at index 2
cp2y = this line's components object at index 3
x = this line's components object at index 2
y = this line's components object at index 3
Where cp is "control point". So you have control point one and control point two with their respective x and y coordinates.
Create bezier paths that each represent separate regions (by doing lineToPoint or similar functions).
UIBezierPath *p1 = [UIBezierPath bezierPath];
[path1 lineToPoint:somePoint];
[pointArray1 addObject:NSStringFromCGPoint(somePoint)];
// create lots of points and close p1 path
Then find some triangulation algorithm for concave shapes that would turn each bezier path to an array of triangles (i.e. instead of storing array of bezier path point coordinates you'd store array of triangles' coordinates (array of array of points). Algorithm and explanations can be found in any game development forum or even on GameDev of stack exchange.
Repeat the bezier path creation and triangulation for each region.
Then having these arrays it's just a matter of simple iterations to check if certain point of interest is in one of these triangles.
update seems that #omz comment renders my answer useless, hence it's just a matter of creating bezier paths and calling method on each of them .)

connect line between two boxes avoiding passing others

I have several boxes (x,y,width,height) randomly scattered around, and some of them need to be linked from point (x1,y1) in box1 to point (x2,y2) in box2 by drawing a line. I am trying to figure a way to make such line avoid passing through any other boxes (other than box1 and box2) by drawing several straight interconnected lines to go around any box in the way (if it is not possible to go with one straight line). The problem is that I don't know an algorithm for such thing (let alone having a technical/common name for it). Would appreciate any help in the form of algorithm or expressed ideas.
Thanks
Assuming that the lines can't be diagonal, here's one simple way. It's based on BFS and will also find the shortest line connecting the points:
Just create a graph, containing one vertex for each point (x, y) and for each point the edges:
((x,y),(x+1,y)) ((x,y),(x-1,y)) ((x,y),(x,y+1)) ((x,y),(x,y-1))
But each of this edges must be present only if it doesn't overlap a box.
Now just do a plain BFS from point (x1,y1) to (x2,y2)
It's really easy to obtain also diagonal lines the same way but you will need 8 edges for each vertex, that are, in addition to the previouses 4:
((x,y),(x-1,y+1)) ((x,y),(x-1,y-1)) ((x,y),(x+1,y-1)) ((x,y),(x+1,y+1))
Still, each edge must be present only if it doesn't overlap a box.
EDIT
If you can't consider space divided into a grid, here's another possibility, it won't give you the very shortest path, though.
Create a graph, in which each box is a vertex and has an edge to any other box that can be reached without the line to overlap a third box. Now find the shortet path using dijkstra between box1 and box2 containing the two points.
Now consider each box to have a small countour that doesn't overlap any other box. This way you can link the entering and the exiting point of each box in the path found through dijistra, passing through the countour.
Put all (x,y) coords of the corners of the boxes in a set V
Add the start- and end coordinates to V.
Create a set of edges E connecting each corner that does not cross any box-side (except for the diagonals in the boxes).
How to check if a line crosses a box side can be done with this algorithm
Now use a path-finding algorithm of your choice, to find a path in the graph (V, E).
If you need a simple algorithm that finds the shortest path, just go with a BFS.
(This will produce a path that goes along the sides of some boxes. If this is undesirable, you could in step 1 put the points at some distance delta from the actual corners.)
If the edges may not be diagonal:
Create a large grid of lines that goes between the boxes.
Throw away the grid-edges that cross a box-side.
Find a path in the grid using a path-finding algorithm of your choice.