| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. | 2 * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 m_visualMetricsIterator = SVGInlineTextMetricsIterator(); | 269 m_visualMetricsIterator = SVGInlineTextMetricsIterator(); |
| 270 | 270 |
| 271 // After all text fragments are stored in their correpsonding SVGInlineTextB
oxes, we can layout individual text chunks. | 271 // After all text fragments are stored in their correpsonding SVGInlineTextB
oxes, we can layout individual text chunks. |
| 272 // Chunk layouting is only performed for line layout boxes, not for path lay
out, where it has already been done. | 272 // Chunk layouting is only performed for line layout boxes, not for path lay
out, where it has already been done. |
| 273 SVGTextChunkBuilder chunkLayoutBuilder; | 273 SVGTextChunkBuilder chunkLayoutBuilder; |
| 274 chunkLayoutBuilder.processTextChunks(m_lineLayoutBoxes); | 274 chunkLayoutBuilder.processTextChunks(m_lineLayoutBoxes); |
| 275 | 275 |
| 276 m_lineLayoutBoxes.clear(); | 276 m_lineLayoutBoxes.clear(); |
| 277 } | 277 } |
| 278 | 278 |
| 279 bool SVGTextLayoutEngine::currentLogicalCharacterAttributes(SVGTextLayoutAttribu
tes*& logicalAttributes) | 279 const SVGTextLayoutAttributes* SVGTextLayoutEngine::nextLogicalAttributes() |
| 280 { | 280 { |
| 281 if (m_layoutAttributesPosition == m_layoutAttributes.size()) | 281 ASSERT(m_layoutAttributesPosition < m_layoutAttributes.size()); |
| 282 return false; | |
| 283 | |
| 284 logicalAttributes = m_layoutAttributes[m_layoutAttributesPosition]; | |
| 285 ASSERT(logicalAttributes); | |
| 286 | |
| 287 if (m_logicalCharacterOffset != logicalAttributes->context()->textLength()) | |
| 288 return true; | |
| 289 | |
| 290 ++m_layoutAttributesPosition; | 282 ++m_layoutAttributesPosition; |
| 291 if (m_layoutAttributesPosition == m_layoutAttributes.size()) | 283 if (m_layoutAttributesPosition == m_layoutAttributes.size()) |
| 292 return false; | 284 return nullptr; |
| 293 | 285 |
| 294 logicalAttributes = m_layoutAttributes[m_layoutAttributesPosition]; | |
| 295 m_logicalMetricsListOffset = 0; | 286 m_logicalMetricsListOffset = 0; |
| 296 m_logicalCharacterOffset = 0; | 287 m_logicalCharacterOffset = 0; |
| 297 return true; | 288 return m_layoutAttributes[m_layoutAttributesPosition]; |
| 298 } | 289 } |
| 299 | 290 |
| 300 bool SVGTextLayoutEngine::currentLogicalCharacterMetrics(SVGTextLayoutAttributes
*& logicalAttributes, SVGTextMetrics& logicalMetrics) | 291 const SVGTextLayoutAttributes* SVGTextLayoutEngine::currentLogicalCharacterMetri
cs(SVGTextMetrics& logicalMetrics) |
| 301 { | 292 { |
| 293 // If we're consumed all layout attributes, there can be no more metrics. |
| 294 if (m_layoutAttributesPosition == m_layoutAttributes.size()) |
| 295 return nullptr; |
| 296 |
| 297 const SVGTextLayoutAttributes* logicalAttributes = m_layoutAttributes[m_layo
utAttributesPosition]; |
| 298 // If we reached the end of the text node associated with the current set |
| 299 // of layout attributes, try to move to the next text node/set of layout |
| 300 // attributes. |
| 301 ASSERT(m_logicalCharacterOffset <= logicalAttributes->context()->textLength(
)); |
| 302 if (m_logicalCharacterOffset == logicalAttributes->context()->textLength())
{ |
| 303 logicalAttributes = nextLogicalAttributes(); |
| 304 if (!logicalAttributes) |
| 305 return nullptr; |
| 306 } |
| 307 |
| 308 // We have set of layout attributes. Find the first non-collapsed text |
| 309 // metrics cell. |
| 302 const Vector<SVGTextMetrics>* metricsList = &logicalAttributes->context()->m
etricsList(); | 310 const Vector<SVGTextMetrics>* metricsList = &logicalAttributes->context()->m
etricsList(); |
| 303 unsigned metricsListSize = metricsList->size(); | 311 unsigned metricsListSize = metricsList->size(); |
| 304 while (true) { | 312 while (true) { |
| 313 // If we run out of metrics, move to the next set of layout attributes. |
| 305 if (m_logicalMetricsListOffset == metricsListSize) { | 314 if (m_logicalMetricsListOffset == metricsListSize) { |
| 306 if (!currentLogicalCharacterAttributes(logicalAttributes)) | 315 logicalAttributes = nextLogicalAttributes(); |
| 307 return false; | 316 if (!logicalAttributes) |
| 317 return nullptr; |
| 308 | 318 |
| 309 metricsList = &logicalAttributes->context()->metricsList(); | 319 metricsList = &logicalAttributes->context()->metricsList(); |
| 310 metricsListSize = metricsList->size(); | 320 metricsListSize = metricsList->size(); |
| 311 continue; | 321 continue; |
| 312 } | 322 } |
| 313 | 323 |
| 314 ASSERT(metricsListSize); | 324 ASSERT(metricsListSize); |
| 315 ASSERT(m_logicalMetricsListOffset < metricsListSize); | 325 ASSERT(m_logicalMetricsListOffset < metricsListSize); |
| 316 logicalMetrics = metricsList->at(m_logicalMetricsListOffset); | 326 logicalMetrics = metricsList->at(m_logicalMetricsListOffset); |
| 317 if (logicalMetrics.isEmpty() || (!logicalMetrics.width() && !logicalMetr
ics.height())) { | 327 if (logicalMetrics.isEmpty() || (!logicalMetrics.width() && !logicalMetr
ics.height())) { |
| 318 advanceToNextLogicalCharacter(logicalMetrics); | 328 advanceToNextLogicalCharacter(logicalMetrics); |
| 319 continue; | 329 continue; |
| 320 } | 330 } |
| 321 | 331 |
| 322 // Stop if we found the next valid logical text metrics object. | 332 // Stop if we found the next valid logical text metrics object. |
| 323 return true; | 333 return logicalAttributes; |
| 324 } | 334 } |
| 325 | 335 |
| 326 ASSERT_NOT_REACHED(); | 336 ASSERT_NOT_REACHED(); |
| 327 return true; | 337 return nullptr; |
| 328 } | 338 } |
| 329 | 339 |
| 330 void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& lo
gicalMetrics) | 340 void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& lo
gicalMetrics) |
| 331 { | 341 { |
| 332 ++m_logicalMetricsListOffset; | 342 ++m_logicalMetricsListOffset; |
| 333 m_logicalCharacterOffset += logicalMetrics.length(); | 343 m_logicalCharacterOffset += logicalMetrics.length(); |
| 334 } | 344 } |
| 335 | 345 |
| 336 void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Line
LayoutSVGInlineText textLineLayout, const ComputedStyle& style) | 346 void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Line
LayoutSVGInlineText textLineLayout, const ComputedStyle& style) |
| 337 { | 347 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 361 | 371 |
| 362 // Main layout algorithm. | 372 // Main layout algorithm. |
| 363 const unsigned boxEndOffset = textBox->start() + textBox->len(); | 373 const unsigned boxEndOffset = textBox->start() + textBox->len(); |
| 364 while (!m_visualMetricsIterator.isAtEnd() && m_visualMetricsIterator.charact
erOffset() < boxEndOffset) { | 374 while (!m_visualMetricsIterator.isAtEnd() && m_visualMetricsIterator.charact
erOffset() < boxEndOffset) { |
| 365 const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics(); | 375 const SVGTextMetrics& visualMetrics = m_visualMetricsIterator.metrics(); |
| 366 if (visualMetrics.isEmpty()) { | 376 if (visualMetrics.isEmpty()) { |
| 367 m_visualMetricsIterator.next(); | 377 m_visualMetricsIterator.next(); |
| 368 continue; | 378 continue; |
| 369 } | 379 } |
| 370 | 380 |
| 371 SVGTextLayoutAttributes* logicalAttributes = nullptr; | 381 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics); |
| 372 if (!currentLogicalCharacterAttributes(logicalAttributes)) | 382 const SVGTextLayoutAttributes* logicalAttributes = currentLogicalCharact
erMetrics(logicalMetrics); |
| 383 if (!logicalAttributes) |
| 373 break; | 384 break; |
| 374 | 385 |
| 375 ASSERT(logicalAttributes); | 386 const SVGCharacterDataMap& characterDataMap = logicalAttributes->charact
erDataMap(); |
| 376 SVGTextMetrics logicalMetrics(SVGTextMetrics::SkippedSpaceMetrics); | |
| 377 if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics)) | |
| 378 break; | |
| 379 | |
| 380 SVGCharacterDataMap& characterDataMap = logicalAttributes->characterData
Map(); | |
| 381 SVGCharacterData data; | 387 SVGCharacterData data; |
| 382 SVGCharacterDataMap::iterator it = characterDataMap.find(m_logicalCharac
terOffset + 1); | 388 SVGCharacterDataMap::const_iterator it = characterDataMap.find(m_logical
CharacterOffset + 1); |
| 383 if (it != characterDataMap.end()) | 389 if (it != characterDataMap.end()) |
| 384 data = it->value; | 390 data = it->value; |
| 385 | 391 |
| 386 // TODO(fs): Use the return value to eliminate the additional | 392 // TODO(fs): Use the return value to eliminate the additional |
| 387 // hash-lookup below when determining if this text box should be tagged | 393 // hash-lookup below when determining if this text box should be tagged |
| 388 // as starting a new text chunk. | 394 // as starting a new text chunk. |
| 389 setCurrentTextPosition(data); | 395 setCurrentTextPosition(data); |
| 390 | 396 |
| 391 // When we've advanced to the box start offset, determine using the orig
inal x/y values, | 397 // When we've advanced to the box start offset, determine using the orig
inal x/y values, |
| 392 // whether this character starts a new text chunk, before doing any furt
her processing. | 398 // whether this character starts a new text chunk, before doing any furt
her processing. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 504 } | 510 } |
| 505 | 511 |
| 506 if (!didStartTextFragment) | 512 if (!didStartTextFragment) |
| 507 return; | 513 return; |
| 508 | 514 |
| 509 // Close last open fragment, if needed. | 515 // Close last open fragment, if needed. |
| 510 recordTextFragment(textBox); | 516 recordTextFragment(textBox); |
| 511 } | 517 } |
| 512 | 518 |
| 513 } // namespace blink | 519 } // namespace blink |
| OLD | NEW |