os/textandloc/fontservices/textshaperplugin/IcuSource/layout/GlyphPositionAdjustments.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/*
sl@0
     2
 *
sl@0
     3
 * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
sl@0
     4
 *
sl@0
     5
 */
sl@0
     6
sl@0
     7
#include "LETypes.h"
sl@0
     8
#include "GlyphPositionAdjustments.h"
sl@0
     9
#include "LEGlyphStorage.h"
sl@0
    10
#include "LEFontInstance.h"
sl@0
    11
sl@0
    12
U_NAMESPACE_BEGIN
sl@0
    13
sl@0
    14
#define CHECK_ALLOCATE_ARRAY(array, type, size) \
sl@0
    15
    if (array == NULL) { \
sl@0
    16
        array = (type *) new type[size]; \
sl@0
    17
    }
sl@0
    18
sl@0
    19
GlyphPositionAdjustments::GlyphPositionAdjustments(le_int32 glyphCount)
sl@0
    20
    : fGlyphCount(glyphCount), fEntryExitPoints(NULL), fAdjustments(NULL)
sl@0
    21
{
sl@0
    22
    fAdjustments = (Adjustment *) new Adjustment[glyphCount];
sl@0
    23
}
sl@0
    24
sl@0
    25
GlyphPositionAdjustments::~GlyphPositionAdjustments()
sl@0
    26
{
sl@0
    27
    delete[] fEntryExitPoints;
sl@0
    28
    delete[] fAdjustments;
sl@0
    29
}
sl@0
    30
sl@0
    31
const LEPoint *GlyphPositionAdjustments::getEntryPoint(le_int32 index, LEPoint &entryPoint) const
sl@0
    32
{
sl@0
    33
    if (fEntryExitPoints == NULL) {
sl@0
    34
        return NULL;
sl@0
    35
    }
sl@0
    36
sl@0
    37
    return fEntryExitPoints[index].getEntryPoint(entryPoint);
sl@0
    38
}
sl@0
    39
sl@0
    40
const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &exitPoint)const
sl@0
    41
{
sl@0
    42
    if (fEntryExitPoints == NULL) {
sl@0
    43
        return NULL;
sl@0
    44
    }
sl@0
    45
sl@0
    46
    return fEntryExitPoints[index].getExitPoint(exitPoint);
sl@0
    47
}
sl@0
    48
sl@0
    49
void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
sl@0
    50
{
sl@0
    51
    CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
sl@0
    52
sl@0
    53
    fEntryExitPoints[index].setEntryPoint(newEntryPoint, baselineIsLogicalEnd);
sl@0
    54
}
sl@0
    55
sl@0
    56
void GlyphPositionAdjustments::setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
sl@0
    57
{
sl@0
    58
    CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
sl@0
    59
sl@0
    60
    fEntryExitPoints[index].setExitPoint(newExitPoint, baselineIsLogicalEnd);
sl@0
    61
}
sl@0
    62
sl@0
    63
void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd)
sl@0
    64
{
sl@0
    65
    CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
sl@0
    66
sl@0
    67
    fEntryExitPoints[index].setCursiveGlyph(baselineIsLogicalEnd);
sl@0
    68
}
sl@0
    69
sl@0
    70
void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance)
sl@0
    71
{
sl@0
    72
    if (! hasCursiveGlyphs()) {
sl@0
    73
        return;
sl@0
    74
    }
sl@0
    75
sl@0
    76
    le_int32 start = 0, end = fGlyphCount, dir = 1;
sl@0
    77
    le_int32 firstExitPoint = -1, lastExitPoint = -1;
sl@0
    78
    LEPoint entryAnchor, exitAnchor, pixels;
sl@0
    79
    LEGlyphID lastExitGlyphID = 0;
sl@0
    80
    float baselineAdjustment = 0;
sl@0
    81
sl@0
    82
    // This removes a possible warning about
sl@0
    83
    // using exitAnchor before it's been initialized.
sl@0
    84
    exitAnchor.fX = exitAnchor.fY = 0;
sl@0
    85
sl@0
    86
    if (rightToLeft) {
sl@0
    87
        start = fGlyphCount - 1;
sl@0
    88
        end = -1;
sl@0
    89
        dir = -1;
sl@0
    90
    }
sl@0
    91
sl@0
    92
    for (le_int32 i = start; i != end; i += dir) {
sl@0
    93
        LEGlyphID glyphID = glyphStorage[i];
sl@0
    94
sl@0
    95
        if (isCursiveGlyph(i)) {
sl@0
    96
            if (lastExitPoint >= 0 && getEntryPoint(i, entryAnchor) != NULL) {
sl@0
    97
                float anchorDiffX = exitAnchor.fX - entryAnchor.fX;
sl@0
    98
                float anchorDiffY = exitAnchor.fY - entryAnchor.fY;
sl@0
    99
sl@0
   100
                baselineAdjustment += anchorDiffY;
sl@0
   101
                adjustYPlacement(i, baselineAdjustment);
sl@0
   102
sl@0
   103
                if (rightToLeft) {
sl@0
   104
                    LEPoint secondAdvance;
sl@0
   105
sl@0
   106
                    fontInstance->getGlyphAdvance(glyphID, pixels);
sl@0
   107
                    fontInstance->pixelsToUnits(pixels, secondAdvance);
sl@0
   108
sl@0
   109
                    adjustXAdvance(i, -(anchorDiffX + secondAdvance.fX));
sl@0
   110
                } else {
sl@0
   111
                    LEPoint firstAdvance;
sl@0
   112
sl@0
   113
                    fontInstance->getGlyphAdvance(lastExitGlyphID, pixels);
sl@0
   114
                    fontInstance->pixelsToUnits(pixels, firstAdvance);
sl@0
   115
sl@0
   116
                    adjustXAdvance(lastExitPoint, anchorDiffX - firstAdvance.fX);
sl@0
   117
                }
sl@0
   118
            }
sl@0
   119
sl@0
   120
            lastExitPoint = i;
sl@0
   121
sl@0
   122
            if (getExitPoint(i, exitAnchor) != NULL) {
sl@0
   123
                if (firstExitPoint < 0) {
sl@0
   124
                    firstExitPoint = i;
sl@0
   125
                }
sl@0
   126
sl@0
   127
                lastExitGlyphID = glyphID;
sl@0
   128
            } else {
sl@0
   129
                if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) {
sl@0
   130
                    le_int32 limit = lastExitPoint + dir;
sl@0
   131
sl@0
   132
                    for (le_int32 j = firstExitPoint; j != limit; j += dir) {
sl@0
   133
                        if (isCursiveGlyph(j)) {
sl@0
   134
                            adjustYPlacement(j, -baselineAdjustment);
sl@0
   135
                        }
sl@0
   136
                    }
sl@0
   137
                }
sl@0
   138
sl@0
   139
                firstExitPoint = lastExitPoint = -1;
sl@0
   140
                baselineAdjustment = 0;
sl@0
   141
            }
sl@0
   142
        }
sl@0
   143
    }
sl@0
   144
}
sl@0
   145
sl@0
   146
LEPoint *GlyphPositionAdjustments::EntryExitPoint::getEntryPoint(LEPoint &entryPoint) const
sl@0
   147
{
sl@0
   148
    if (fFlags & EEF_HAS_ENTRY_POINT) {
sl@0
   149
        entryPoint = fEntryPoint;
sl@0
   150
        return &entryPoint;
sl@0
   151
    }
sl@0
   152
sl@0
   153
    return NULL;
sl@0
   154
}
sl@0
   155
sl@0
   156
LEPoint *GlyphPositionAdjustments::EntryExitPoint::getExitPoint(LEPoint &exitPoint) const
sl@0
   157
{
sl@0
   158
    if (fFlags & EEF_HAS_EXIT_POINT) {
sl@0
   159
        exitPoint = fExitPoint;
sl@0
   160
        return &exitPoint;
sl@0
   161
    }
sl@0
   162
sl@0
   163
    return NULL;
sl@0
   164
}
sl@0
   165
sl@0
   166
U_NAMESPACE_END