1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 /*
  27  *
  28  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
  29  *
  30  */
  31 
  32 #ifndef __GLYPHPOSITIONADJUSTMENTS_H
  33 #define __GLYPHPOSITIONADJUSTMENTS_H
  34 
  35 #include "LETypes.h"
  36 #include "OpenTypeTables.h"
  37 
  38 class LEGlyphStorage;
  39 class LEFontInstance;
  40 
  41 class GlyphPositionAdjustments
  42 {
  43 private:
  44     class Adjustment {
  45     public:
  46 
  47         inline Adjustment();
  48         inline Adjustment(float xPlace, float yPlace, float xAdv, float yAdv, le_int32 baseOff = -1);
  49         inline ~Adjustment();
  50 
  51         inline float    getXPlacement() const;
  52         inline float    getYPlacement() const;
  53         inline float    getXAdvance() const;
  54         inline float    getYAdvance() const;
  55 
  56         inline le_int32 getBaseOffset() const;
  57 
  58         inline void     setXPlacement(float newXPlacement);
  59         inline void     setYPlacement(float newYPlacement);
  60         inline void     setXAdvance(float newXAdvance);
  61         inline void     setYAdvance(float newYAdvance);
  62 
  63         inline void     setBaseOffset(le_int32 newBaseOffset);
  64 
  65         inline void    adjustXPlacement(float xAdjustment);
  66         inline void    adjustYPlacement(float yAdjustment);
  67         inline void    adjustXAdvance(float xAdjustment);
  68         inline void    adjustYAdvance(float yAdjustment);
  69 
  70     private:
  71         float xPlacement;
  72         float yPlacement;
  73         float xAdvance;
  74         float yAdvance;
  75 
  76         le_int32 baseOffset;
  77 
  78         // allow copying of this class because all of its fields are simple types
  79     };
  80 
  81     class EntryExitPoint
  82     {
  83     public:
  84         inline EntryExitPoint();
  85         inline ~EntryExitPoint();
  86 
  87         inline le_bool isCursiveGlyph() const;
  88         inline le_bool baselineIsLogicalEnd() const;
  89 
  90         LEPoint *getEntryPoint(LEPoint &entryPoint) const;
  91         LEPoint *getExitPoint(LEPoint &exitPoint) const;
  92 
  93         inline void setEntryPoint(LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd);
  94         inline void setExitPoint(LEPoint &newExitPoint, le_bool baselineIsLogicalEnd);
  95         inline void setCursiveGlyph(le_bool baselineIsLogicalEnd);
  96 
  97     private:
  98         enum EntryExitFlags
  99         {
 100             EEF_HAS_ENTRY_POINT         = 0x80000000L,
 101             EEF_HAS_EXIT_POINT          = 0x40000000L,
 102             EEF_IS_CURSIVE_GLYPH        = 0x20000000L,
 103             EEF_BASELINE_IS_LOGICAL_END = 0x10000000L
 104         };
 105 
 106         le_uint32 fFlags;
 107         LEPoint fEntryPoint;
 108         LEPoint fExitPoint;
 109     };
 110 
 111     le_int32 fGlyphCount;
 112     EntryExitPoint *fEntryExitPoints;
 113     Adjustment *fAdjustments;
 114 
 115     GlyphPositionAdjustments();
 116 
 117 public:
 118     GlyphPositionAdjustments(le_int32 glyphCount);
 119     ~GlyphPositionAdjustments();
 120 
 121     inline le_bool hasCursiveGlyphs() const;
 122     inline le_bool isCursiveGlyph(le_int32 index) const;
 123     inline le_bool baselineIsLogicalEnd(le_int32 index) const;
 124 
 125     const LEPoint *getEntryPoint(le_int32 index, LEPoint &entryPoint) const;
 126     const LEPoint *getExitPoint(le_int32 index, LEPoint &exitPoint) const;
 127 
 128     inline float getXPlacement(le_int32 index) const;
 129     inline float getYPlacement(le_int32 index) const;
 130     inline float getXAdvance(le_int32 index) const;
 131     inline float getYAdvance(le_int32 index) const;
 132 
 133     inline le_int32 getBaseOffset(le_int32 index) const;
 134 
 135     inline void setXPlacement(le_int32 index, float newXPlacement);
 136     inline void setYPlacement(le_int32 index, float newYPlacement);
 137     inline void setXAdvance(le_int32 index, float newXAdvance);
 138     inline void setYAdvance(le_int32 index, float newYAdvance);
 139 
 140     inline void setBaseOffset(le_int32 index, le_int32 newBaseOffset);
 141 
 142     inline void adjustXPlacement(le_int32 index, float xAdjustment);
 143     inline void adjustYPlacement(le_int32 index, float yAdjustment);
 144     inline void adjustXAdvance(le_int32 index, float xAdjustment);
 145     inline void adjustYAdvance(le_int32 index, float yAdjustment);
 146 
 147     void setEntryPoint(le_int32 index, LEPoint &newEntryPoint,
 148         le_bool baselineIsLogicalEnd);
 149     void setExitPoint(le_int32 index, LEPoint &newExitPoint,
 150         le_bool baselineIsLogicalEnd);
 151     void setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd);
 152 
 153     void applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft,
 154         const LEFontInstance *fontInstance);
 155 };
 156 
 157 inline GlyphPositionAdjustments::Adjustment::Adjustment()
 158   : xPlacement(0), yPlacement(0), xAdvance(0), yAdvance(0), baseOffset(-1)
 159 {
 160     // nothing else to do!
 161 }
 162 
 163 inline GlyphPositionAdjustments::Adjustment::Adjustment(float xPlace, float yPlace,
 164     float xAdv, float yAdv, le_int32 baseOff)
 165   : xPlacement(xPlace), yPlacement(yPlace), xAdvance(xAdv), yAdvance(yAdv),
 166     baseOffset(baseOff)
 167 {
 168     // nothing else to do!
 169 }
 170 
 171 inline GlyphPositionAdjustments::Adjustment::~Adjustment()
 172 {
 173     // nothing to do!
 174 }
 175 
 176 inline float GlyphPositionAdjustments::Adjustment::getXPlacement() const
 177 {
 178     return xPlacement;
 179 }
 180 
 181 inline float GlyphPositionAdjustments::Adjustment::getYPlacement() const
 182 {
 183     return yPlacement;
 184 }
 185 
 186 inline float GlyphPositionAdjustments::Adjustment::getXAdvance() const
 187 {
 188     return xAdvance;
 189 }
 190 
 191 inline float GlyphPositionAdjustments::Adjustment::getYAdvance() const
 192 {
 193     return yAdvance;
 194 }
 195 
 196 inline le_int32 GlyphPositionAdjustments::Adjustment::getBaseOffset() const
 197 {
 198     return baseOffset;
 199 }
 200 
 201 inline void GlyphPositionAdjustments::Adjustment::setXPlacement(float newXPlacement)
 202 {
 203     xPlacement = newXPlacement;
 204 }
 205 
 206 inline void GlyphPositionAdjustments::Adjustment::setYPlacement(float newYPlacement)
 207 {
 208     yPlacement = newYPlacement;
 209 }
 210 
 211 inline void GlyphPositionAdjustments::Adjustment::setXAdvance(float newXAdvance)
 212 {
 213     xAdvance = newXAdvance;
 214 }
 215 
 216 inline void GlyphPositionAdjustments::Adjustment::setYAdvance(float newYAdvance)
 217 {
 218     yAdvance = newYAdvance;
 219 }
 220 
 221 inline void GlyphPositionAdjustments::Adjustment::setBaseOffset(le_int32 newBaseOffset)
 222 {
 223     baseOffset = newBaseOffset;
 224 }
 225 
 226 inline void GlyphPositionAdjustments::Adjustment::adjustXPlacement(float xAdjustment)
 227 {
 228     xPlacement += xAdjustment;
 229 }
 230 
 231 inline void GlyphPositionAdjustments::Adjustment::adjustYPlacement(float yAdjustment)
 232 {
 233     yPlacement += yAdjustment;
 234 }
 235 
 236 inline void GlyphPositionAdjustments::Adjustment::adjustXAdvance(float xAdjustment)
 237 {
 238     xAdvance += xAdjustment;
 239 }
 240 
 241 inline void GlyphPositionAdjustments::Adjustment::adjustYAdvance(float yAdjustment)
 242 {
 243     yAdvance += yAdjustment;
 244 }
 245 
 246 inline GlyphPositionAdjustments::EntryExitPoint::EntryExitPoint()
 247     : fFlags(0)
 248 {
 249     fEntryPoint.fX = fEntryPoint.fY = fExitPoint.fX = fEntryPoint.fY = 0;
 250 }
 251 
 252 inline GlyphPositionAdjustments::EntryExitPoint::~EntryExitPoint()
 253 {
 254     // nothing special to do
 255 }
 256 
 257 inline le_bool GlyphPositionAdjustments::EntryExitPoint::isCursiveGlyph() const
 258 {
 259     return (fFlags & EEF_IS_CURSIVE_GLYPH) != 0;
 260 }
 261 
 262 inline le_bool GlyphPositionAdjustments::EntryExitPoint::baselineIsLogicalEnd() const
 263 {
 264     return (fFlags & EEF_BASELINE_IS_LOGICAL_END) != 0;
 265 }
 266 
 267 inline void GlyphPositionAdjustments::EntryExitPoint::setEntryPoint(
 268     LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd)
 269 {
 270     if (baselineIsLogicalEnd) {
 271         fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH |
 272         EEF_BASELINE_IS_LOGICAL_END);
 273     } else {
 274         fFlags |= (EEF_HAS_ENTRY_POINT | EEF_IS_CURSIVE_GLYPH);
 275     }
 276 
 277     fEntryPoint = newEntryPoint;
 278 }
 279 
 280 inline void GlyphPositionAdjustments::EntryExitPoint::setExitPoint(
 281     LEPoint &newExitPoint, le_bool baselineIsLogicalEnd)
 282 {
 283     if (baselineIsLogicalEnd) {
 284         fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH |
 285             EEF_BASELINE_IS_LOGICAL_END);
 286     } else {
 287         fFlags |= (EEF_HAS_EXIT_POINT | EEF_IS_CURSIVE_GLYPH);
 288     }
 289 
 290     fExitPoint  = newExitPoint;
 291 }
 292 
 293 inline void GlyphPositionAdjustments::EntryExitPoint::setCursiveGlyph(
 294     le_bool baselineIsLogicalEnd)
 295 {
 296     if (baselineIsLogicalEnd) {
 297         fFlags |= (EEF_IS_CURSIVE_GLYPH | EEF_BASELINE_IS_LOGICAL_END);
 298     } else {
 299         fFlags |= EEF_IS_CURSIVE_GLYPH;
 300     }
 301 }
 302 
 303 inline le_bool GlyphPositionAdjustments::isCursiveGlyph(le_int32 index) const
 304 {
 305     return fEntryExitPoints != NULL && fEntryExitPoints[index].isCursiveGlyph();
 306 }
 307 
 308 inline le_bool GlyphPositionAdjustments::baselineIsLogicalEnd(le_int32 index) const
 309 {
 310     return fEntryExitPoints != NULL && fEntryExitPoints[index].baselineIsLogicalEnd();
 311 }
 312 
 313 inline float GlyphPositionAdjustments::getXPlacement(le_int32 index) const
 314 {
 315     return fAdjustments[index].getXPlacement();
 316 }
 317 
 318 inline float GlyphPositionAdjustments::getYPlacement(le_int32 index) const
 319 {
 320     return fAdjustments[index].getYPlacement();
 321 }
 322 
 323 inline float GlyphPositionAdjustments::getXAdvance(le_int32 index) const
 324 {
 325     return fAdjustments[index].getXAdvance();
 326 }
 327 
 328 inline float GlyphPositionAdjustments::getYAdvance(le_int32 index) const
 329 {
 330     return fAdjustments[index].getYAdvance();
 331 }
 332 
 333 
 334 inline le_int32 GlyphPositionAdjustments::getBaseOffset(le_int32 index) const
 335 {
 336     return fAdjustments[index].getBaseOffset();
 337 }
 338 
 339 inline void GlyphPositionAdjustments::setXPlacement(le_int32 index, float newXPlacement)
 340 {
 341     fAdjustments[index].setXPlacement(newXPlacement);
 342 }
 343 
 344 inline void GlyphPositionAdjustments::setYPlacement(le_int32 index, float newYPlacement)
 345 {
 346     fAdjustments[index].setYPlacement(newYPlacement);
 347 }
 348 
 349 inline void GlyphPositionAdjustments::setXAdvance(le_int32 index, float newXAdvance)
 350 {
 351     fAdjustments[index].setXAdvance(newXAdvance);
 352 }
 353 
 354 inline void GlyphPositionAdjustments::setYAdvance(le_int32 index, float newYAdvance)
 355 {
 356     fAdjustments[index].setYAdvance(newYAdvance);
 357 }
 358 
 359 inline void GlyphPositionAdjustments::setBaseOffset(le_int32 index, le_int32 newBaseOffset)
 360 {
 361     fAdjustments[index].setBaseOffset(newBaseOffset);
 362 }
 363 
 364 inline void GlyphPositionAdjustments::adjustXPlacement(le_int32 index, float xAdjustment)
 365 {
 366     fAdjustments[index].adjustXPlacement(xAdjustment);
 367 }
 368 
 369 inline void GlyphPositionAdjustments::adjustYPlacement(le_int32 index, float yAdjustment)
 370 {
 371     fAdjustments[index].adjustYPlacement(yAdjustment);
 372 }
 373 
 374 inline void GlyphPositionAdjustments::adjustXAdvance(le_int32 index, float xAdjustment)
 375 {
 376     fAdjustments[index].adjustXAdvance(xAdjustment);
 377 }
 378 
 379 inline void GlyphPositionAdjustments::adjustYAdvance(le_int32 index, float yAdjustment)
 380 {
 381     fAdjustments[index].adjustYAdvance(yAdjustment);
 382 }
 383 
 384 inline le_bool GlyphPositionAdjustments::hasCursiveGlyphs() const
 385 {
 386     return fEntryExitPoints != NULL;
 387 }
 388 
 389 #endif