本文整理汇总了C++中SVGTextMetrics类的典型用法代码示例。如果您正苦于以下问题:C++ SVGTextMetrics类的具体用法?C++ SVGTextMetrics怎么用?C++ SVGTextMetrics使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SVGTextMetrics类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: currentLogicalCharacterMetrics
bool SVGTextLayoutEngine::currentLogicalCharacterMetrics(SVGTextLayoutAttributes*& logicalAttributes, SVGTextMetrics& logicalMetrics)
{
const Vector<SVGTextMetrics>* textMetricsValues = &logicalAttributes->textMetricsValues();
unsigned textMetricsSize = textMetricsValues->size();
while (true) {
if (m_logicalMetricsListOffset == textMetricsSize) {
if (!currentLogicalCharacterAttributes(logicalAttributes))
return false;
textMetricsValues = &logicalAttributes->textMetricsValues();
textMetricsSize = textMetricsValues->size();
continue;
}
ASSERT(textMetricsSize);
ASSERT(m_logicalMetricsListOffset < textMetricsSize);
logicalMetrics = textMetricsValues->at(m_logicalMetricsListOffset);
if (logicalMetrics.isEmpty() || (!logicalMetrics.width() && !logicalMetrics.height())) {
advanceToNextLogicalCharacter(logicalMetrics);
continue;
}
// Stop if we found the next valid logical text metrics object.
return true;
}
ASSERT_NOT_REACHED();
return true;
}
示例2: FloatPoint
bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGTextFragment& fragment) const
{
EndPositionOfCharacterData* data = static_cast<EndPositionOfCharacterData*>(queryData);
int startPosition = data->position;
int endPosition = startPosition + 1;
if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
return false;
data->endPosition = FloatPoint(fragment.x, fragment.y);
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition + 1);
if (queryData->isVerticalText)
data->endPosition.move(0, metrics.height());
else
data->endPosition.move(metrics.width(), 0);
AffineTransform fragmentTransform;
fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
if (fragmentTransform.isIdentity())
return true;
data->endPosition = fragmentTransform.mapPoint(data->endPosition);
return true;
}
示例3: measureTextRenderer
static void measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data, bool processRenderer)
{
ASSERT(text);
SVGTextLayoutAttributes* attributes = text->layoutAttributes();
Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues();
if (processRenderer) {
if (data->allCharactersMap)
attributes->clear();
else
textMetricsValues->clear();
}
SVGTextMetricsCalculator calculator(text);
bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
unsigned surrogatePairCharacters = 0;
unsigned skippedCharacters = 0;
unsigned textPosition = 0;
unsigned textLength = calculator.textLength();
SVGTextMetrics currentMetrics;
for (; textPosition < textLength; textPosition += currentMetrics.length()) {
currentMetrics = calculator.computeMetricsForCharacter(textPosition);
if (!currentMetrics.length())
break;
bool characterIsWhiteSpace = calculator.characterIsWhiteSpace(textPosition);
if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
if (processRenderer)
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
if (data->allCharactersMap)
skippedCharacters += currentMetrics.length();
continue;
}
if (processRenderer) {
if (data->allCharactersMap) {
const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + textPosition - skippedCharacters - surrogatePairCharacters + 1);
if (it != data->allCharactersMap->end())
attributes->characterDataMap().set(textPosition + 1, it->value);
}
textMetricsValues->append(currentMetrics);
}
if (data->allCharactersMap && calculator.characterStartsSurrogatePair(textPosition))
surrogatePairCharacters++;
data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
}
if (!data->allCharactersMap)
return;
data->valueListPosition += textPosition - skippedCharacters;
}
示例4: calculateGlyphAdvanceAndOrientation
float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVerticalText, const SVGTextMetrics& metrics, float angle, float& xOrientationShift, float& yOrientationShift) const
{
bool orientationIsMultiplyOf180Degrees = glyphOrientationIsMultiplyOf180Degrees(angle);
// The function is based on spec requirements:
//
// Spec: If the 'glyph-orientation-horizontal' results in an orientation angle that is not a multiple of
// of 180 degrees, then the current text position is incremented according to the vertical metrics of the glyph.
//
// Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of
// 180 degrees, then the current text position is incremented according to the horizontal metrics of the glyph.
const FontMetrics& fontMetrics = m_font.fontMetrics();
float ascent = fontMetrics.floatAscent() / m_effectiveZoom;
float descent = fontMetrics.floatDescent() / m_effectiveZoom;
// Vertical orientation handling.
if (isVerticalText) {
float ascentMinusDescent = ascent - descent;
if (!angle) {
xOrientationShift = (ascentMinusDescent - metrics.width()) / 2;
yOrientationShift = ascent;
} else if (angle == 180) {
xOrientationShift = (ascentMinusDescent + metrics.width()) / 2;
} else if (angle == 270) {
yOrientationShift = metrics.width();
xOrientationShift = ascentMinusDescent;
}
// Vertical advance calculation.
if (angle && !orientationIsMultiplyOf180Degrees)
return metrics.width();
return metrics.height();
}
// Horizontal orientation handling.
if (angle == 90) {
yOrientationShift = -metrics.width();
} else if (angle == 180) {
xOrientationShift = metrics.width();
yOrientationShift = -ascent;
} else if (angle == 270) {
xOrientationShift = metrics.width();
}
// Horizontal advance calculation.
if (angle && !orientationIsMultiplyOf180Degrees)
return metrics.height();
return metrics.width();
}
示例5: subStringLengthCallback
bool SVGTextQuery::subStringLengthCallback(Data* queryData, const SVGTextFragment& fragment) const
{
SubStringLengthData* data = static_cast<SubStringLengthData*>(queryData);
int startPosition = data->startPosition;
int endPosition = startPosition + data->length;
if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
return false;
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, endPosition - startPosition);
data->subStringLength += queryData->isVerticalText ? metrics.height() : metrics.width();
return false;
}
示例6: ASSERT
SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition)
{
if (m_bidiRun) {
if (textPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
m_bidiRun = m_bidiRun->next();
// New BiDi run means new reference position for measurements, so reset |m_totalWidth|.
m_totalWidth = 0;
}
ASSERT(m_bidiRun);
ASSERT(static_cast<int>(textPosition) < m_bidiRun->stop());
m_textDirection = m_bidiRun->direction();
}
unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength, m_textDirection);
ASSERT(metrics.length() == metricsLength);
unsigned startPosition = m_bidiRun ? m_bidiRun->start() : 0;
ASSERT(startPosition <= textPosition);
SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, startPosition, textPosition - startPosition + metricsLength, m_textDirection);
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
// when laying out the glyph "in context" (with it's surrounding characters) it changes due to shaping.
// So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
// not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
if (currentWidth != metrics.width())
metrics.setWidth(currentWidth);
m_totalWidth = complexStartToCurrentMetrics.width();
return metrics;
}
示例7: calculateGlyphBoundaries
static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const SVGTextFragment& fragment, int startPosition, FloatRect& extent)
{
float scalingFactor = queryData->textRenderer->scalingFactor();
ASSERT(scalingFactor);
extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor));
if (startPosition) {
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition);
if (queryData->isVerticalText)
extent.move(0, metrics.height());
else
extent.move(metrics.width(), 0);
}
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, 1);
extent.setSize(FloatSize(metrics.width(), metrics.height()));
AffineTransform fragmentTransform;
fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
if (fragmentTransform.isIdentity())
return;
extent = fragmentTransform.mapRect(extent);
}
示例8: calculateGlyphPositionWithoutTransform
static FloatPoint calculateGlyphPositionWithoutTransform(const QueryData* queryData, const SVGTextFragment& fragment, int offsetInFragment)
{
float glyphOffsetInDirection = 0;
if (offsetInFragment) {
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textLayoutObject, fragment.characterOffset, offsetInFragment, queryData->textBox->direction());
if (queryData->isVerticalText)
glyphOffsetInDirection = metrics.height();
else
glyphOffsetInDirection = metrics.width();
}
if (!queryData->textBox->isLeftToRightDirection()) {
float fragmentExtent = queryData->isVerticalText ? fragment.height : fragment.width;
glyphOffsetInDirection = fragmentExtent - glyphOffsetInDirection;
}
FloatPoint glyphPosition(fragment.x, fragment.y);
if (queryData->isVerticalText)
glyphPosition.move(0, glyphOffsetInDirection);
else
glyphPosition.move(glyphOffsetInDirection, 0);
return glyphPosition;
}
示例9: characterStartsSurrogatePair
SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsigned textPosition)
{
unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength, m_textDirection);
ASSERT(metrics.length() == metricsLength);
unsigned startPosition = m_bidiRun ? m_bidiRun->start() : 0;
ASSERT(startPosition <= textPosition);
SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, startPosition, textPosition - startPosition + metricsLength, m_textDirection);
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
// when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping.
// So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
// not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
if (currentWidth != metrics.width())
metrics.setWidth(currentWidth);
m_totalWidth = complexStartToCurrentMetrics.width();
return metrics;
}
示例10: advanceToNextLogicalCharacter
void SVGTextLayoutEngine::advanceToNextLogicalCharacter(const SVGTextMetrics& logicalMetrics)
{
++m_logicalMetricsListOffset;
m_logicalCharacterOffset += logicalMetrics.length();
}
示例11: parentDefinesTextLength
void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, RenderSVGInlineText* text, const RenderStyle* style)
{
SVGElement* lengthContext = static_cast<SVGElement*>(text->parent()->node());
RenderObject* textParent = text->parent();
bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false;
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
m_visualMetricsListOffset = 0;
m_visualCharacterOffset = 0;
Vector<SVGTextMetrics>& textMetricsValues = text->layoutAttributes().textMetricsValues();
const UChar* characters = text->characters();
const Font& font = style->font();
SVGTextLayoutEngineSpacing spacingLayout(font);
SVGTextLayoutEngineBaseline baselineLayout(font);
bool didStartTextFragment = false;
bool applySpacingToNextCharacter = false;
float lastAngle = 0;
float baselineShift = baselineLayout.calculateBaselineShift(svgStyle, lengthContext);
baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVerticalText, text);
// Main layout algorithm.
while (true) {
// Find the start of the current text box in this list, respecting ligatures.
SVGTextMetrics visualMetrics = SVGTextMetrics::emptyMetrics();
if (!currentVisualCharacterMetrics(textBox, text, visualMetrics))
break;
if (visualMetrics == SVGTextMetrics::emptyMetrics()) {
advanceToNextVisualCharacter(visualMetrics);
continue;
}
SVGTextLayoutAttributes logicalAttributes;
if (!currentLogicalCharacterAttributes(logicalAttributes))
break;
SVGTextMetrics logicalMetrics = SVGTextMetrics::emptyMetrics();
if (!currentLogicalCharacterMetrics(logicalAttributes, logicalMetrics))
break;
Vector<float>& xValues = logicalAttributes.xValues();
Vector<float>& yValues = logicalAttributes.yValues();
Vector<float>& dxValues = logicalAttributes.dxValues();
Vector<float>& dyValues = logicalAttributes.dyValues();
Vector<float>& rotateValues = logicalAttributes.rotateValues();
float x = xValues.at(m_logicalCharacterOffset);
float y = yValues.at(m_logicalCharacterOffset);
// When we've advanced to the box start offset, determine using the original x/y values,
// whether this character starts a new text chunk, before doing any further processing.
if (m_visualCharacterOffset == textBox->start())
textBox->setStartsNewTextChunk(logicalAttributes.context()->characterStartsNewTextChunk(m_logicalCharacterOffset));
float angle = 0;
if (!rotateValues.isEmpty()) {
float newAngle = rotateValues.at(m_logicalCharacterOffset);
if (newAngle != SVGTextLayoutAttributes::emptyValue())
angle = newAngle;
}
// Calculate glyph orientation angle.
const UChar* currentCharacter = characters + m_visualCharacterOffset;
float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m_isVerticalText, svgStyle, *currentCharacter);
// Calculate glyph advance & x/y orientation shifts.
float xOrientationShift = 0;
float yOrientationShift = 0;
float glyphAdvance = baselineLayout.calculateGlyphAdvanceAndOrientation(m_isVerticalText, visualMetrics, orientationAngle, xOrientationShift, yOrientationShift);
// Assign current text position to x/y values, if needed.
updateCharacerPositionIfNeeded(x, y);
// Apply dx/dy value adjustments to current text position, if needed.
updateRelativePositionAdjustmentsIfNeeded(dxValues, dyValues);
// Calculate SVG Fonts kerning, if needed.
float kerning = spacingLayout.calculateSVGKerning(m_isVerticalText, visualMetrics.glyph());
// Calculate CSS 'kerning', 'letter-spacing' and 'word-spacing' for next character, if needed.
float spacing = spacingLayout.calculateCSSKerningAndSpacing(svgStyle, lengthContext, currentCharacter);
float textPathOffset = 0;
if (m_inPathLayout) {
float scaledGlyphAdvance = glyphAdvance * m_textPathScaling;
if (m_isVerticalText) {
// If there's an absolute y position available, it marks the beginning of a new position along the path.
if (y != SVGTextLayoutAttributes::emptyValue())
m_textPathCurrentOffset = y + m_textPathStartOffset;
m_textPathCurrentOffset += m_dy - kerning;
m_dy = 0;
//.........这里部分代码省略.........
示例12: advanceToNextVisualCharacter
void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& visualMetrics)
{
++m_visualMetricsListOffset;
m_visualCharacterOffset += visualMetrics.length();
}