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