]> git.saurik.com Git - apple/icu.git/blob - icuSources/layout/CursiveAttachmentSubtables.cpp
ICU-6.2.4.tar.gz
[apple/icu.git] / icuSources / layout / CursiveAttachmentSubtables.cpp
1 /*
2 * %W% %E%
3 *
4 * (C) Copyright IBM Corp. 1998, 1999, 2000, 2001, 2002 - All Rights Reserved
5 *
6 */
7
8 #include "LETypes.h"
9 #include "LEFontInstance.h"
10 #include "OpenTypeTables.h"
11 #include "GlyphPositioningTables.h"
12 #include "CursiveAttachmentSubtables.h"
13 #include "AnchorTables.h"
14 #include "GlyphIterator.h"
15 #include "GlyphPositionAdjustments.h"
16 #include "OpenTypeUtilities.h"
17 #include "LESwaps.h"
18
19 U_NAMESPACE_BEGIN
20
21 le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
22 {
23 LEGlyphID glyphID = glyphIterator->getCurrGlyphID();
24 le_int32 coverageIndex = getGlyphCoverage(glyphID);
25 le_uint16 eeCount = SWAPW(entryExitCount);
26
27 if (coverageIndex < 0 || coverageIndex >= eeCount) {
28 glyphIterator->resetCursiveLastExitPoint();
29 return 0;
30 }
31
32 LEPoint entryAnchor, exitAnchor, pixels;
33
34 if (glyphIterator->hasCursiveLastExitPoint() && entryExitRecords[coverageIndex].entryAnchor != 0) {
35 Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
36
37 const AnchorTable *entryAnchorTable = (const AnchorTable *) ((char *) this + entryOffset);
38
39 entryAnchorTable->getAnchor(glyphID, fontInstance, entryAnchor);
40 glyphIterator->getCursiveLastExitPoint(exitAnchor);
41
42 float anchorDiffX = exitAnchor.fX - entryAnchor.fX;
43 float anchorDiffY = exitAnchor.fY - entryAnchor.fY;
44 float baselineAdjustment = glyphIterator->getCursiveBaselineAdjustment();
45
46 if (glyphIterator->isRightToLeft()) {
47 LEPoint secondAdvance;
48
49 fontInstance->getGlyphAdvance(glyphID, pixels);
50 fontInstance->pixelsToUnits(pixels, secondAdvance);
51
52 glyphIterator->adjustCurrGlyphPositionAdjustment(0, anchorDiffY + baselineAdjustment, -(anchorDiffX + secondAdvance.fX), 0);
53 } else {
54 LEPoint firstAdvance;
55
56 fontInstance->getGlyphAdvance(glyphIterator->getCursiveLastGlyphID(), pixels);
57 fontInstance->pixelsToUnits(pixels, firstAdvance);
58
59 glyphIterator->adjustCursiveLastGlyphPositionAdjustment(0, 0, anchorDiffX - firstAdvance.fX, 0);
60 glyphIterator->adjustCurrGlyphPositionAdjustment(0, anchorDiffY + baselineAdjustment, 0, 0);
61 }
62
63 glyphIterator->setCursiveBaselineAdjustment(anchorDiffY + baselineAdjustment);
64 }
65
66 Offset exitOffset = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
67
68 if (exitOffset != 0) {
69 const AnchorTable *exitAnchorTable = (const AnchorTable *) ((char *) this + exitOffset);
70
71 exitAnchorTable->getAnchor(glyphID, fontInstance, exitAnchor);
72
73 if (!glyphIterator->hasCursiveFirstExitPoint()) {
74 glyphIterator->setCursiveFirstExitPoint();
75 }
76
77 glyphIterator->setCursiveLastExitPoint(exitAnchor);
78 } else {
79 /*
80 * We've got a glyph which is covered but doesn't have an
81 * exit point. We call setCursiveLastExitPoint just to set
82 * the position of this glyph, then resetCursiveLastExitPoint
83 * to do any baseline adjustments that are required for the
84 * sequence of attached glyphs.
85 *
86 * NOTE: we don't really care about the value of
87 * extiAnchor, because after we reset the last exit
88 * point, it won't be used. This is a bit of a hack.
89 * There should probably be a setCursiveLastExitPoint
90 * call that doesn't take an anchor...
91 */
92 glyphIterator->setCursiveLastExitPoint(exitAnchor);
93 glyphIterator->resetCursiveLastExitPoint();
94 }
95
96 return 1;
97 }
98
99 U_NAMESPACE_END