1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/GlyphIterator.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,479 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "OpenTypeTables.h"
1.12 +#include "GlyphDefinitionTables.h"
1.13 +#include "GlyphPositionAdjustments.h"
1.14 +#include "GlyphIterator.h"
1.15 +#include "LEGlyphStorage.h"
1.16 +#include "Lookups.h"
1.17 +#include "LESwaps.h"
1.18 +
1.19 +U_NAMESPACE_BEGIN
1.20 +
1.21 +GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags, LETag theFeatureTag,
1.22 + const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
1.23 + : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
1.24 + glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
1.25 + srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureTag(theFeatureTag),
1.26 + glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
1.27 +
1.28 +{
1.29 + le_int32 glyphCount = glyphStorage.getGlyphCount();
1.30 +
1.31 + if (theGlyphDefinitionTableHeader != NULL) {
1.32 + glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
1.33 + markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
1.34 + }
1.35 +
1.36 + nextLimit = glyphCount;
1.37 +
1.38 + if (rightToLeft) {
1.39 + direction = -1;
1.40 + position = glyphCount;
1.41 + nextLimit = -1;
1.42 + prevLimit = glyphCount;
1.43 + }
1.44 +}
1.45 +
1.46 +GlyphIterator::GlyphIterator(GlyphIterator &that)
1.47 + : glyphStorage(that.glyphStorage)
1.48 +{
1.49 + direction = that.direction;
1.50 + position = that.position;
1.51 + nextLimit = that.nextLimit;
1.52 + prevLimit = that.prevLimit;
1.53 +
1.54 + glyphPositionAdjustments = that.glyphPositionAdjustments;
1.55 + srcIndex = that.srcIndex;
1.56 + destIndex = that.destIndex;
1.57 + lookupFlags = that.lookupFlags;
1.58 + featureTag = that.featureTag;
1.59 + glyphClassDefinitionTable = that.glyphClassDefinitionTable;
1.60 + markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
1.61 +}
1.62 +
1.63 +GlyphIterator::GlyphIterator(GlyphIterator &that, LETag newFeatureTag)
1.64 + : glyphStorage(that.glyphStorage)
1.65 +{
1.66 + direction = that.direction;
1.67 + position = that.position;
1.68 + nextLimit = that.nextLimit;
1.69 + prevLimit = that.prevLimit;
1.70 +
1.71 + glyphPositionAdjustments = that.glyphPositionAdjustments;
1.72 + srcIndex = that.srcIndex;
1.73 + destIndex = that.destIndex;
1.74 + lookupFlags = that.lookupFlags;
1.75 + featureTag = newFeatureTag;
1.76 + glyphClassDefinitionTable = that.glyphClassDefinitionTable;
1.77 + markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
1.78 +}
1.79 +
1.80 +GlyphIterator::GlyphIterator(GlyphIterator &that, le_uint16 newLookupFlags)
1.81 + : glyphStorage(that.glyphStorage)
1.82 +{
1.83 + direction = that.direction;
1.84 + position = that.position;
1.85 + nextLimit = that.nextLimit;
1.86 + prevLimit = that.prevLimit;
1.87 +
1.88 + glyphPositionAdjustments = that.glyphPositionAdjustments;
1.89 + srcIndex = that.srcIndex;
1.90 + destIndex = that.destIndex;
1.91 + lookupFlags = newLookupFlags;
1.92 + featureTag = that.featureTag;
1.93 + glyphClassDefinitionTable = that.glyphClassDefinitionTable;
1.94 + markAttachClassDefinitionTable = that.markAttachClassDefinitionTable;
1.95 +}
1.96 +
1.97 +GlyphIterator::~GlyphIterator()
1.98 +{
1.99 + // nothing to do, right?
1.100 +}
1.101 +
1.102 +void GlyphIterator::reset(le_uint16 newLookupFlags, LETag newFeatureTag)
1.103 +{
1.104 + position = prevLimit;
1.105 + featureTag = newFeatureTag;
1.106 + lookupFlags = newLookupFlags;
1.107 +}
1.108 +
1.109 +LEGlyphID *GlyphIterator::insertGlyphs(le_int32 count, LEErrorCode& success)
1.110 +{
1.111 + return glyphStorage.insertGlyphs(position, count, success);
1.112 +}
1.113 +
1.114 +le_int32 GlyphIterator::applyInsertions()
1.115 +{
1.116 + le_int32 newGlyphCount = glyphStorage.applyInsertions();
1.117 +
1.118 + if (direction < 0) {
1.119 + prevLimit = newGlyphCount;
1.120 + } else {
1.121 + nextLimit = newGlyphCount;
1.122 + }
1.123 +
1.124 + return newGlyphCount;
1.125 +}
1.126 +
1.127 +le_int32 GlyphIterator::getCurrStreamPosition() const
1.128 +{
1.129 + return position;
1.130 +}
1.131 +
1.132 +le_bool GlyphIterator::isRightToLeft() const
1.133 +{
1.134 + return direction < 0;
1.135 +}
1.136 +
1.137 +le_bool GlyphIterator::ignoresMarks() const
1.138 +{
1.139 + return (lookupFlags & lfIgnoreMarks) != 0;
1.140 +}
1.141 +
1.142 +le_bool GlyphIterator::baselineIsLogicalEnd() const
1.143 +{
1.144 + return (lookupFlags & lfBaselineIsLogicalEnd) != 0;
1.145 +}
1.146 +
1.147 +LEGlyphID GlyphIterator::getCurrGlyphID() const
1.148 +{
1.149 + if (direction < 0) {
1.150 + if (position <= nextLimit || position >= prevLimit) {
1.151 + return 0xFFFF;
1.152 + }
1.153 + } else {
1.154 + if (position <= prevLimit || position >= nextLimit) {
1.155 + return 0xFFFF;
1.156 + }
1.157 + }
1.158 +
1.159 + return glyphStorage[position];
1.160 +}
1.161 +
1.162 +void GlyphIterator::getCursiveEntryPoint(LEPoint &entryPoint) const
1.163 +{
1.164 + if (direction < 0) {
1.165 + if (position <= nextLimit || position >= prevLimit) {
1.166 + return;
1.167 + }
1.168 + } else {
1.169 + if (position <= prevLimit || position >= nextLimit) {
1.170 + return;
1.171 + }
1.172 + }
1.173 +
1.174 + glyphPositionAdjustments->getEntryPoint(position, entryPoint);
1.175 +}
1.176 +
1.177 +void GlyphIterator::getCursiveExitPoint(LEPoint &exitPoint) const
1.178 +{
1.179 + if (direction < 0) {
1.180 + if (position <= nextLimit || position >= prevLimit) {
1.181 + return;
1.182 + }
1.183 + } else {
1.184 + if (position <= prevLimit || position >= nextLimit) {
1.185 + return;
1.186 + }
1.187 + }
1.188 +
1.189 + glyphPositionAdjustments->getExitPoint(position, exitPoint);
1.190 +}
1.191 +
1.192 +void GlyphIterator::setCurrGlyphID(TTGlyphID glyphID)
1.193 +{
1.194 + LEGlyphID glyph = glyphStorage[position];
1.195 +
1.196 + glyphStorage[position] = LE_SET_GLYPH(glyph, glyphID);
1.197 +}
1.198 +
1.199 +void GlyphIterator::setCurrStreamPosition(le_int32 newPosition)
1.200 +{
1.201 + if (direction < 0) {
1.202 + if (newPosition >= prevLimit) {
1.203 + position = prevLimit;
1.204 + return;
1.205 + }
1.206 +
1.207 + if (newPosition <= nextLimit) {
1.208 + position = nextLimit;
1.209 + return;
1.210 + }
1.211 + } else {
1.212 + if (newPosition <= prevLimit) {
1.213 + position = prevLimit;
1.214 + return;
1.215 + }
1.216 +
1.217 + if (newPosition >= nextLimit) {
1.218 + position = nextLimit;
1.219 + return;
1.220 + }
1.221 + }
1.222 +
1.223 + position = newPosition - direction;
1.224 + next();
1.225 +}
1.226 +
1.227 +void GlyphIterator::setCurrGlyphBaseOffset(le_int32 baseOffset)
1.228 +{
1.229 + if (direction < 0) {
1.230 + if (position <= nextLimit || position >= prevLimit) {
1.231 + return;
1.232 + }
1.233 + } else {
1.234 + if (position <= prevLimit || position >= nextLimit) {
1.235 + return;
1.236 + }
1.237 + }
1.238 +
1.239 + glyphPositionAdjustments->setBaseOffset(position, baseOffset);
1.240 +}
1.241 +
1.242 +void GlyphIterator::adjustCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
1.243 + float xAdvanceAdjust, float yAdvanceAdjust)
1.244 +{
1.245 + if (direction < 0) {
1.246 + if (position <= nextLimit || position >= prevLimit) {
1.247 + return;
1.248 + }
1.249 + } else {
1.250 + if (position <= prevLimit || position >= nextLimit) {
1.251 + return;
1.252 + }
1.253 + }
1.254 +
1.255 + glyphPositionAdjustments->adjustXPlacement(position, xPlacementAdjust);
1.256 + glyphPositionAdjustments->adjustYPlacement(position, yPlacementAdjust);
1.257 + glyphPositionAdjustments->adjustXAdvance(position, xAdvanceAdjust);
1.258 + glyphPositionAdjustments->adjustYAdvance(position, yAdvanceAdjust);
1.259 +}
1.260 +
1.261 +void GlyphIterator::setCurrGlyphPositionAdjustment(float xPlacementAdjust, float yPlacementAdjust,
1.262 + float xAdvanceAdjust, float yAdvanceAdjust)
1.263 +{
1.264 + if (direction < 0) {
1.265 + if (position <= nextLimit || position >= prevLimit) {
1.266 + return;
1.267 + }
1.268 + } else {
1.269 + if (position <= prevLimit || position >= nextLimit) {
1.270 + return;
1.271 + }
1.272 + }
1.273 +
1.274 + glyphPositionAdjustments->setXPlacement(position, xPlacementAdjust);
1.275 + glyphPositionAdjustments->setYPlacement(position, yPlacementAdjust);
1.276 + glyphPositionAdjustments->setXAdvance(position, xAdvanceAdjust);
1.277 + glyphPositionAdjustments->setYAdvance(position, yAdvanceAdjust);
1.278 +}
1.279 +
1.280 +void GlyphIterator::setCursiveEntryPoint(LEPoint &entryPoint)
1.281 +{
1.282 + if (direction < 0) {
1.283 + if (position <= nextLimit || position >= prevLimit) {
1.284 + return;
1.285 + }
1.286 + } else {
1.287 + if (position <= prevLimit || position >= nextLimit) {
1.288 + return;
1.289 + }
1.290 + }
1.291 +
1.292 + glyphPositionAdjustments->setEntryPoint(position, entryPoint, baselineIsLogicalEnd());
1.293 +}
1.294 +
1.295 +void GlyphIterator::setCursiveExitPoint(LEPoint &exitPoint)
1.296 +{
1.297 + if (direction < 0) {
1.298 + if (position <= nextLimit || position >= prevLimit) {
1.299 + return;
1.300 + }
1.301 + } else {
1.302 + if (position <= prevLimit || position >= nextLimit) {
1.303 + return;
1.304 + }
1.305 + }
1.306 +
1.307 + glyphPositionAdjustments->setExitPoint(position, exitPoint, baselineIsLogicalEnd());
1.308 +}
1.309 +
1.310 +void GlyphIterator::setCursiveGlyph()
1.311 +{
1.312 + if (direction < 0) {
1.313 + if (position <= nextLimit || position >= prevLimit) {
1.314 + return;
1.315 + }
1.316 + } else {
1.317 + if (position <= prevLimit || position >= nextLimit) {
1.318 + return;
1.319 + }
1.320 + }
1.321 +
1.322 + glyphPositionAdjustments->setCursiveGlyph(position, baselineIsLogicalEnd());
1.323 +}
1.324 +
1.325 +le_bool GlyphIterator::filterGlyph(le_uint32 index) const
1.326 +{
1.327 + LEGlyphID glyphID = glyphStorage[index];
1.328 + le_int32 glyphClass = gcdNoGlyphClass;
1.329 +
1.330 + if (LE_GET_GLYPH(glyphID) >= 0xFFFE) {
1.331 + return TRUE;
1.332 + }
1.333 +
1.334 + if (glyphClassDefinitionTable != NULL) {
1.335 + glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
1.336 + }
1.337 +
1.338 + switch (glyphClass)
1.339 + {
1.340 + case gcdNoGlyphClass:
1.341 + return FALSE;
1.342 +
1.343 + case gcdSimpleGlyph:
1.344 + return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
1.345 +
1.346 + case gcdLigatureGlyph:
1.347 + return (lookupFlags & lfIgnoreLigatures) != 0;
1.348 +
1.349 + case gcdMarkGlyph:
1.350 + {
1.351 + if ((lookupFlags & lfIgnoreMarks) != 0) {
1.352 + return TRUE;
1.353 + }
1.354 +
1.355 + le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
1.356 +
1.357 + if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
1.358 + return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
1.359 + }
1.360 +
1.361 + return FALSE;
1.362 + }
1.363 +
1.364 + case gcdComponentGlyph:
1.365 + return (lookupFlags & lfIgnoreBaseGlyphs) != 0;
1.366 +
1.367 + default:
1.368 + return FALSE;
1.369 + }
1.370 +}
1.371 +
1.372 +static const LETag emptyTag = 0;
1.373 +static const LETag defaultTag = 0xFFFFFFFF;
1.374 +
1.375 +le_bool GlyphIterator::hasFeatureTag() const
1.376 +{
1.377 + if (featureTag == defaultTag || featureTag == emptyTag) {
1.378 + return TRUE;
1.379 + }
1.380 +
1.381 + LEErrorCode success = LE_NO_ERROR;
1.382 + const LETag *tagList = (const LETag *) glyphStorage.getAuxData(position, success);
1.383 +
1.384 + if (tagList != NULL) {
1.385 + for (le_int32 tag = 0; tagList[tag] != emptyTag; tag += 1) {
1.386 + if (tagList[tag] == featureTag) {
1.387 + return TRUE;
1.388 + }
1.389 + }
1.390 + }
1.391 +
1.392 + return FALSE;
1.393 +}
1.394 +
1.395 +le_bool GlyphIterator::findFeatureTag()
1.396 +{
1.397 + while (nextInternal()) {
1.398 + if (hasFeatureTag()) {
1.399 + prevInternal();
1.400 + return TRUE;
1.401 + }
1.402 + }
1.403 +
1.404 + return FALSE;
1.405 +}
1.406 +
1.407 +
1.408 +le_bool GlyphIterator::nextInternal(le_uint32 delta)
1.409 +{
1.410 + le_int32 newPosition = position;
1.411 +
1.412 + while (newPosition != nextLimit && delta > 0) {
1.413 + do {
1.414 + newPosition += direction;
1.415 + } while (newPosition != nextLimit && filterGlyph(newPosition));
1.416 +
1.417 + delta -= 1;
1.418 + }
1.419 +
1.420 + position = newPosition;
1.421 +
1.422 + return position != nextLimit;
1.423 +}
1.424 +
1.425 +le_bool GlyphIterator::next(le_uint32 delta)
1.426 +{
1.427 + return nextInternal(delta) && hasFeatureTag();
1.428 +}
1.429 +
1.430 +le_bool GlyphIterator::prevInternal(le_uint32 delta)
1.431 +{
1.432 + le_int32 newPosition = position;
1.433 +
1.434 + while (newPosition != prevLimit && delta > 0) {
1.435 + do {
1.436 + newPosition -= direction;
1.437 + } while (newPosition != prevLimit && filterGlyph(newPosition));
1.438 +
1.439 + delta -= 1;
1.440 + }
1.441 +
1.442 + position = newPosition;
1.443 +
1.444 + return position != prevLimit;
1.445 +}
1.446 +
1.447 +le_bool GlyphIterator::prev(le_uint32 delta)
1.448 +{
1.449 + return prevInternal(delta) && hasFeatureTag();
1.450 +}
1.451 +
1.452 +le_int32 GlyphIterator::getMarkComponent(le_int32 markPosition) const
1.453 +{
1.454 + le_int32 component = 0;
1.455 + le_int32 posn;
1.456 +
1.457 + for (posn = position; posn != markPosition; posn += direction) {
1.458 + if (glyphStorage[posn] == 0xFFFE) {
1.459 + component += 1;
1.460 + }
1.461 + }
1.462 +
1.463 + return component;
1.464 +}
1.465 +
1.466 +// This is basically prevInternal except that it
1.467 +// doesn't take a delta argument, and it doesn't
1.468 +// filter out 0xFFFE glyphs.
1.469 +le_bool GlyphIterator::findMark2Glyph()
1.470 +{
1.471 + le_int32 newPosition = position;
1.472 +
1.473 + do {
1.474 + newPosition -= direction;
1.475 + } while (newPosition != prevLimit && glyphStorage[newPosition] != 0xFFFE && filterGlyph(newPosition));
1.476 +
1.477 + position = newPosition;
1.478 +
1.479 + return position != prevLimit;
1.480 +}
1.481 +
1.482 +U_NAMESPACE_END