~ubuntu-branches/ubuntu/quantal/icu/quantal

« back to all changes in this revision

Viewing changes to source/layout/MarkToLigaturePosnSubtables.cpp

  • Committer: Package Import Robot
  • Author(s): Yves Arrouye
  • Date: 2002-03-03 15:31:13 UTC
  • Revision ID: package-import@ubuntu.com-20020303153113-3ssceqlq45xbmbnc
Tags: upstream-2.0-2.1pre20020303
ImportĀ upstreamĀ versionĀ 2.0-2.1pre20020303

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * %W% %E%
 
3
 *
 
4
 * (C) Copyright IBM Corp. 1998, 1999, 2000, 2001 - All Rights Reserved
 
5
 *
 
6
 */
 
7
 
 
8
#include "LETypes.h"
 
9
#include "LEFontInstance.h"
 
10
#include "OpenTypeTables.h"
 
11
#include "AnchorTables.h"
 
12
#include "MarkArrays.h"
 
13
#include "GlyphPositioningTables.h"
 
14
#include "AttachmentPosnSubtables.h"
 
15
#include "MarkToLigaturePosnSubtables.h"
 
16
#include "GlyphIterator.h"
 
17
#include "LESwaps.h"
 
18
 
 
19
U_NAMESPACE_BEGIN
 
20
 
 
21
LEGlyphID MarkToLigaturePositioningSubtable::findLigatureGlyph(GlyphIterator *glyphIterator) const
 
22
{
 
23
    if (glyphIterator->prev()) {
 
24
        return glyphIterator->getCurrGlyphID();
 
25
    }
 
26
 
 
27
    return 0xFFFF;
 
28
}
 
29
 
 
30
le_int32 MarkToLigaturePositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
 
31
{
 
32
    LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
 
33
    le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
 
34
 
 
35
    if (markCoverage < 0) {
 
36
        // markGlyph isn't a covered mark glyph
 
37
        return 0;
 
38
    }
 
39
 
 
40
    LEPoint markAnchor;
 
41
    const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
 
42
    le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
 
43
    le_uint16 mcCount = SWAPW(classCount);
 
44
 
 
45
    if (markClass < 0 || markClass >= mcCount) {
 
46
        // markGlyph isn't in the mark array or its
 
47
        // mark class is too big. The table is mal-formed!
 
48
        return 0;
 
49
    }
 
50
 
 
51
    // FIXME: we probably don't want to find a ligature before a previous base glyph...
 
52
    GlyphIterator ligatureIterator(*glyphIterator, lfIgnoreMarks /*| lfIgnoreBaseGlyphs*/);
 
53
    LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator);
 
54
    le_int32 ligatureCoverage = getBaseCoverage((LEGlyphID) ligatureGlyph);
 
55
    const LigatureArray *ligatureArray = (const LigatureArray *) ((char *) this + SWAPW(baseArrayOffset));
 
56
    le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount);
 
57
 
 
58
    if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) {
 
59
        // The ligature glyph isn't covered, or the coverage
 
60
        // index is too big. The latter means that the
 
61
        // table is mal-formed...
 
62
        return 0;
 
63
    }
 
64
 
 
65
    le_int32 markPosition = glyphIterator->getCurrStreamPosition();
 
66
    Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]);
 
67
    const LigatureAttachTable *ligatureAttachTable = (const LigatureAttachTable *) ((char *) ligatureArray + ligatureAttachOffset);
 
68
        le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount);
 
69
    le_int32 component = ligatureIterator.getMarkComponent(markPosition);
 
70
 
 
71
        if (component >= componentCount) {
 
72
                // should really just bail at this point...
 
73
                component = componentCount - 1;
 
74
        }
 
75
 
 
76
    const ComponentRecord *componentRecord = &ligatureAttachTable->componentRecordArray[component * mcCount];
 
77
    Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]);
 
78
    const AnchorTable *anchorTable = (const AnchorTable *) ((char *) ligatureAttachTable + anchorTableOffset);
 
79
    LEPoint ligatureAnchor, markAdvance, pixels;
 
80
 
 
81
    anchorTable->getAnchor(ligatureGlyph, fontInstance, ligatureAnchor);
 
82
 
 
83
    fontInstance->getGlyphAdvance(markGlyph, pixels);
 
84
    fontInstance->pixelsToUnits(pixels, markAdvance);
 
85
 
 
86
    float anchorDiffX = ligatureAnchor.fX - markAnchor.fX;
 
87
    float anchorDiffY = ligatureAnchor.fY - markAnchor.fY;
 
88
 
 
89
    if (glyphIterator->isRightToLeft()) {
 
90
        float adjustX = markAdvance.fX + anchorDiffX;
 
91
 
 
92
        glyphIterator->adjustCurrGlyphPositionAdjustment(anchorDiffX, -anchorDiffY, -adjustX, anchorDiffY);
 
93
    } else {
 
94
        LEPoint ligatureAdvance;
 
95
 
 
96
        fontInstance->getGlyphAdvance(ligatureGlyph, pixels);
 
97
        fontInstance->pixelsToUnits(pixels, ligatureAdvance);
 
98
 
 
99
        float adjustX = ligatureAdvance.fX - anchorDiffX;
 
100
        float advAdjustX = adjustX - markAdvance.fX;
 
101
 
 
102
        glyphIterator->adjustCurrGlyphPositionAdjustment(-adjustX, -anchorDiffY, advAdjustX, anchorDiffY);
 
103
    }
 
104
 
 
105
    return 1;
 
106
}
 
107
 
 
108
U_NAMESPACE_END