本文整理汇总了C++中GlyphBuffer::glyphAt方法的典型用法代码示例。如果您正苦于以下问题:C++ GlyphBuffer::glyphAt方法的具体用法?C++ GlyphBuffer::glyphAt怎么用?C++ GlyphBuffer::glyphAt使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GlyphBuffer
的用法示例。
在下文中一共展示了GlyphBuffer::glyphAt方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1:
TEST(GlyphBufferTest, ReverseForSimpleRTL) {
RefPtr<SimpleFontData> font1 = TestSimpleFontData::create();
RefPtr<SimpleFontData> font2 = TestSimpleFontData::create();
GlyphBuffer glyphBuffer;
glyphBuffer.add(42, font1.get(), 10);
glyphBuffer.add(43, font1.get(), 15);
glyphBuffer.add(44, font2.get(), 25);
EXPECT_FALSE(glyphBuffer.isEmpty());
EXPECT_EQ(3u, glyphBuffer.size());
glyphBuffer.reverseForSimpleRTL(30, 100);
EXPECT_FALSE(glyphBuffer.isEmpty());
EXPECT_EQ(3u, glyphBuffer.size());
EXPECT_EQ(44, glyphBuffer.glyphAt(0));
EXPECT_EQ(43, glyphBuffer.glyphAt(1));
EXPECT_EQ(42, glyphBuffer.glyphAt(2));
EXPECT_EQ(font2.get(), glyphBuffer.fontDataAt(0));
EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(1));
EXPECT_EQ(font1.get(), glyphBuffer.fontDataAt(2));
EXPECT_EQ(70, glyphBuffer.xOffsetAt(0));
EXPECT_EQ(75, glyphBuffer.xOffsetAt(1));
EXPECT_EQ(85, glyphBuffer.xOffsetAt(2));
}
示例2: drawEmphasisMarks
void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const GlyphBuffer& glyphBuffer, const AtomicString& mark, const FloatPoint& point) const
{
FontCachePurgePreventer purgePreventer;
GlyphData markGlyphData;
if (!getEmphasisMarkGlyphData(mark, markGlyphData))
return;
const SimpleFontData* markFontData = markGlyphData.fontData;
ASSERT(markFontData);
if (!markFontData)
return;
Glyph markGlyph = markGlyphData.glyph;
Glyph spaceGlyph = markFontData->spaceGlyph();
float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());
GlyphBuffer markBuffer;
for (int i = 0; i + 1 < glyphBuffer.size(); ++i) {
float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
float advance = glyphBuffer.advanceAt(i).width() - middleOfLastGlyph + middleOfNextGlyph;
markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
middleOfLastGlyph = middleOfNextGlyph;
}
markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spaceGlyph, markFontData, 0);
drawGlyphBuffer(context, run, markBuffer, startPoint);
}
示例3: floatWidthUsingSVGFont
float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, Glyph& glyphId) const
{
WidthIterator it(&font, run);
GlyphBuffer glyphBuffer;
charsConsumed += it.advance(run.length(), &glyphBuffer);
glyphId = !glyphBuffer.isEmpty() ? glyphBuffer.glyphAt(0) : 0;
return it.runWidthSoFar();
}
示例4: textRun
// Tests that filling a glyph buffer for a specific range returns the same
// results when shaping word by word as when shaping the full run in one go.
TEST_F(CachingWordShaperTest, CommonAccentLeftToRightFillGlyphBuffer) {
// "/. ." with an accent mark over the first dot.
const UChar str[] = {0x2F, 0x301, 0x2E, 0x20, 0x2E, 0x0};
TextRun textRun(str, 5);
CachingWordShaper shaper(cache.get());
GlyphBuffer glyphBuffer;
shaper.fillGlyphBuffer(&font, textRun, fallbackFonts, &glyphBuffer, 0, 3);
std::unique_ptr<ShapeCache> referenceCache = wrapUnique(new ShapeCache());
CachingWordShaper referenceShaper(referenceCache.get());
GlyphBuffer referenceGlyphBuffer;
font.setCanShapeWordByWordForTesting(false);
referenceShaper.fillGlyphBuffer(&font, textRun, fallbackFonts,
&referenceGlyphBuffer, 0, 3);
ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2));
}
示例5: textRun
// Tests that filling a glyph buffer for a specific range returns the same
// results when shaping word by word as when shaping the full run in one go.
TEST_F(CachingWordShaperTest, CommonAccentRightToLeftFillGlyphBuffer)
{
// "[] []" with an accent mark over the last square bracket.
const UChar str[] = { 0x5B, 0x5D, 0x20, 0x5B, 0x301, 0x5D, 0x0 };
TextRun textRun(str, 6);
textRun.setDirection(RTL);
CachingWordShaper shaper(cache.get());
GlyphBuffer glyphBuffer;
shaper.fillGlyphBuffer(&font, textRun, fallbackFonts, &glyphBuffer, 1, 6);
OwnPtr<ShapeCache> referenceCache = adoptPtr(new ShapeCache());
CachingWordShaper referenceShaper(referenceCache.get());
GlyphBuffer referenceGlyphBuffer;
font.setCanShapeWordByWordForTesting(false);
referenceShaper.fillGlyphBuffer(&font, textRun, fallbackFonts,
&referenceGlyphBuffer, 1, 6);
ASSERT_EQ(5u, referenceGlyphBuffer.size());
ASSERT_EQ(referenceGlyphBuffer.size(), glyphBuffer.size());
ASSERT_EQ(referenceGlyphBuffer.glyphAt(0), glyphBuffer.glyphAt(0));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(1), glyphBuffer.glyphAt(1));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(2), glyphBuffer.glyphAt(2));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(3), glyphBuffer.glyphAt(3));
ASSERT_EQ(referenceGlyphBuffer.glyphAt(4), glyphBuffer.glyphAt(4));
}
示例6: drawGlyphs
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
if (context->paintingDisabled())
return;
bool shouldFill = context->textDrawingMode() & TextModeFill;
bool shouldStroke = context->textDrawingMode() & TextModeStroke;
// Stroking text should always take the complex path.
ASSERT(!shouldStroke);
// Shadowed text should always take the complex path.
ASSERT(context->contextShadow()->m_type == ContextShadow::NoShadow);
if (!shouldFill && !shouldStroke)
return;
QVector<quint32> glyphIndexes;
QVector<QPointF> positions;
glyphIndexes.reserve(numGlyphs);
positions.reserve(numGlyphs);
float x = 0;
for (int i = 0; i < numGlyphs; ++i) {
Glyph glyph = glyphBuffer.glyphAt(from + i);
float advance = glyphBuffer.advanceAt(from + i);
if (!glyph)
continue;
glyphIndexes.append(glyph);
positions.append(QPointF(x, 0));
x += advance;
}
QGlyphs qtGlyphs;
qtGlyphs.setGlyphIndexes(glyphIndexes);
qtGlyphs.setPositions(positions);
qtGlyphs.setFont(fontData->platformData().rawFont());
QPainter* painter = context->platformContext();
QPen previousPen = painter->pen();
painter->setPen(fillPenForContext(context));
painter->drawGlyphs(point, qtGlyphs);
painter->setPen(previousPen);
}
示例7: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* sfont, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
int i = 0;
FloatPoint pos(point);
float w=0, h=0;
UChar c=0;
void* dc = (void *)graphicsContext->platformContext();
WKCPeerFont pf;
WKCFloatRect clip;
WKCFloatPoint pp;
if (!dc) return;
pf.fFont = sfont->platformData().Font();
if (!pf.fFont) return;
const FontPlatformData& pd(sfont->platformData());
pf.fRequestedSize = pd.requestSize();
pf.fCreatedSize = pd.createdSize();
pf.fWeight = pd.weight();
pf.fItalic = pd.isItalic();
pf.fScale = pd.scale();
pf.fiScale = pd.iscale();
pf.fCanScale = pd.canScale();
pf.fFontId = (void *)pd.hash();
pos.setY(pos.y() - (float)pd.ascent()*pd.scale());
h = (pd.lineSpacing()) * pd.scale();
for (i=0; i<numGlyphs; i++) {
float advance = 0.f;
c = fixedChar(glyphBuffer.glyphAt(from + i));
if (!c) continue;
advance = glyphBuffer.advanceAt(from + i);
w = wkcFontGetClipWidthPeer(pf.fFont, c) * pd.scale();
clip.fX = pos.x();
clip.fY = pos.y();
clip.fWidth = w;
clip.fHeight = h;
pp.fX = pos.x();
pp.fY = pos.y();
wkcDrawContextDrawCharPeer(dc, (unsigned int)c, &pp, &clip, &pf);
pos.move(advance, 0);
}
}
示例8: ASSERT
SVGGlyphToPathTranslator::SVGGlyphToPathTranslator(const GlyphBuffer& glyphBuffer, const FloatPoint& point, const SVGFontData& svgFontData, SVGFontElement& fontElement, const int from, const int numGlyphs, float scale, bool isVerticalText)
: m_glyphBuffer(glyphBuffer)
, m_svgFontData(svgFontData)
, m_currentPoint(point)
, m_glyphOrigin(m_svgFontData.horizontalOriginX() * scale, m_svgFontData.horizontalOriginY() * scale)
, m_index(from)
, m_glyph(glyphBuffer.glyphAt(m_index))
, m_fontElement(fontElement)
, m_stoppingPoint(numGlyphs + from)
, m_scale(scale)
, m_isVerticalText(isVerticalText)
{
ASSERT(glyphBuffer.size() > m_index);
if (m_glyph) {
m_svgGlyph = m_fontElement.svgGlyphForGlyph(m_glyph);
ASSERT(!m_svgGlyph.isPartOfLigature);
ASSERT(m_svgGlyph.tableEntry == m_glyph);
SVGGlyphElement::inheritUnspecifiedAttributes(m_svgGlyph, &m_svgFontData);
}
moveToNextValidGlyph();
}
示例9: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext,
const SimpleFontData* font,
const GlyphBuffer& glyphBuffer,
int from,
int numGlyphs,
const FloatPoint& point) const
{
SkColor color = graphicsContext->platformContext()->effectiveFillColor();
unsigned char alpha = SkColorGetA(color);
// Skip 100% transparent text; no need to draw anything.
if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
return;
TransparencyAwareGlyphPainter painter(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
// We draw the glyphs in chunks to avoid having to do a heap allocation for
// the arrays of characters and advances. Since ExtTextOut is the
// lowest-level text output function on Windows, there should be little
// penalty for splitting up the text. On the other hand, the buffer cannot
// be bigger than 4094 or the function will fail.
const int kMaxBufferLength = 256;
Vector<WORD, kMaxBufferLength> glyphs;
Vector<int, kMaxBufferLength> advances;
int glyphIndex = 0; // The starting glyph of the current chunk.
int curAdvance = 0; // How far from the left the current chunk is.
while (glyphIndex < numGlyphs) {
// How many chars will be in this chunk?
int curLen = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
glyphs.resize(curLen);
advances.resize(curLen);
int curWidth = 0;
for (int i = 0; i < curLen; ++i, ++glyphIndex) {
glyphs[i] = glyphBuffer.glyphAt(from + glyphIndex);
advances[i] = static_cast<int>(glyphBuffer.advanceAt(from + glyphIndex));
// Bug 26088 - very large positive or negative runs can fail to
// render so we clamp the size here. In the specs, negative
// letter-spacing is implementation-defined, so this should be
// fine, and it matches Safari's implementation. The call actually
// seems to crash if kMaxNegativeRun is set to somewhere around
// -32830, so we give ourselves a little breathing room.
const int maxNegativeRun = -32768;
const int maxPositiveRun = 32768;
if ((curWidth + advances[i] < maxNegativeRun) || (curWidth + advances[i] > maxPositiveRun))
advances[i] = 0;
curWidth += advances[i];
}
// Actually draw the glyphs (with retry on failure).
bool success = false;
for (int executions = 0; executions < 2; ++executions) {
success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], curAdvance);
if (!success && executions == 0) {
// Ask the browser to load the font for us and retry.
ChromiumBridge::ensureFontLoaded(font->platformData().hfont());
continue;
}
break;
}
if (!success)
LOG_ERROR("Unable to draw the glyphs after second attempt");
curAdvance += curWidth;
}
}
示例10: drawGDIGlyphs
//.........这里部分代码省略.........
SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
if (translation.width() || translation.height()) {
XFORM xform;
xform.eM11 = 1.0;
xform.eM12 = 0;
xform.eM21 = 0;
xform.eM22 = 1.0;
xform.eDx = translation.width();
xform.eDy = translation.height();
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
}
if (drawingMode == TextModeFill) {
XFORM xform;
xform.eM11 = 1.0;
xform.eM12 = 0;
xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0;
xform.eM22 = 1.0;
xform.eDx = point.x();
xform.eDy = point.y();
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
if (font->syntheticBoldOffset()) {
xform.eM21 = 0;
xform.eDx = font->syntheticBoldOffset();
xform.eDy = 0;
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
}
} else {
XFORM xform;
GetWorldTransform(hdc, &xform);
AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy);
CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity;
if (font->platformData().syntheticOblique())
initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0));
initialGlyphTransform.tx = 0;
initialGlyphTransform.ty = 0;
CGContextRef cgContext = graphicsContext->platformContext();
CGContextSaveGState(cgContext);
BOOL fontSmoothingEnabled = false;
SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0);
CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled);
CGContextScaleCTM(cgContext, 1.0, -1.0);
CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height()));
for (unsigned i = 0; i < numGlyphs; ++i) {
RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
CGContextSaveGState(cgContext);
CGContextConcatCTM(cgContext, initialGlyphTransform);
if (drawingMode & TextModeFill) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
if (font->syntheticBoldOffset()) {
CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}
if (drawingMode & TextModeStroke) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
if (font->syntheticBoldOffset()) {
CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}
CGContextRestoreGState(cgContext);
CGContextTranslateCTM(cgContext, gdiAdvances[i], 0);
}
CGContextRestoreGState(cgContext);
}
if (drawIntoBitmap) {
UInt8* buffer = bitmap->buffer();
unsigned bufferLength = bitmap->bufferLength();
for (unsigned i = 0; i < bufferLength; i += 4) {
// Use green, which is always in the middle.
UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255;
buffer[i] = fillColor.blue();
buffer[i + 1] = fillColor.green();
buffer[i + 2] = fillColor.red();
buffer[i + 3] = alpha;
}
graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location());
} else
graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
}
示例11: drawSVGGlyphs
void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const TextRun& run, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
SVGFontElement* fontElement = 0;
SVGFontFaceElement* fontFaceElement = 0;
const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
if (!fontElement || !fontFaceElement)
return;
// We can only paint SVGFonts if a context is available.
RenderObject* renderObject = renderObjectFromRun(run);
ASSERT(renderObject);
bool isVerticalText = false;
if (RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject)) {
RenderStyle* parentRenderObjectStyle = parentRenderObject->style();
ASSERT(parentRenderObjectStyle);
isVerticalText = parentRenderObjectStyle->svgStyle().isVerticalWritingMode();
}
float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
FloatPoint glyphOrigin;
glyphOrigin.setX(svgFontData->horizontalOriginX() * scale);
glyphOrigin.setY(svgFontData->horizontalOriginY() * scale);
unsigned short resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
FloatPoint currentPoint = point;
for (int i = 0; i < numGlyphs; ++i) {
Glyph glyph = glyphBuffer.glyphAt(from + i);
if (!glyph)
continue;
float advance = glyphBuffer.advanceAt(from + i);
SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
ASSERT(!svgGlyph.isPartOfLigature);
ASSERT(svgGlyph.tableEntry == glyph);
SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, svgFontData);
// FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations).
if (svgGlyph.pathData.isEmpty()) {
if (isVerticalText)
currentPoint.move(0, advance);
else
currentPoint.move(advance, 0);
continue;
}
if (isVerticalText) {
glyphOrigin.setX(svgGlyph.verticalOriginX * scale);
glyphOrigin.setY(svgGlyph.verticalOriginY * scale);
}
AffineTransform glyphPathTransform;
glyphPathTransform.translate(currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y());
glyphPathTransform.scale(scale, -scale);
Path glyphPath = svgGlyph.pathData;
glyphPath.transform(glyphPathTransform);
SVGRenderSupport::fillOrStrokePath(context, resourceMode, glyphPath);
if (isVerticalText)
currentPoint.move(0, advance);
else
currentPoint.move(advance, 0);
}
}
示例12: drawGlyphs
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const
{
// compile-time assert
SkASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t));
if (numGlyphs == 1 && glyphBuffer.glyphAt(from) == 0x3) {
// Webkit likes to draw end text control command for some reason
// Just ignore it
return;
}
SkPaint paint;
if (!setupForText(&paint, gc, font)) {
return;
}
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs), storage2(numGlyphs), storage3(numGlyphs);
SkPoint* pos = storage.get();
SkCanvas* canvas = gc->platformContext()->recordingCanvas();
/* We need an array of [x,y,x,y,x,y,...], but webkit is giving us
point.xy + [width, height, width, height, ...], so we have to convert
*/
if (font->platformData().orientation() == Vertical) {
float yOffset = SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
gc->platformContext()->setTextOffset(FloatSize(0.0f, -yOffset)); // compensate for offset in bounds calculation
y += yOffset;
}
if (EmojiFont::IsAvailable()) {
// set filtering, to make scaled images look nice(r)
paint.setFilterBitmap(true);
SkMatrix rotator;
rotator.reset();
if (font->platformData().orientation() == Vertical) {
canvas->save();
canvas->rotate(-90);
rotator.setRotate(90);
}
int localIndex = 0;
int localCount = 0;
for (int i = 0; i < numGlyphs; i++) {
if (EmojiFont::IsEmojiGlyph(glyphs[i])) {
if (localCount) {
rotator.mapPoints(&pos[localIndex], localCount);
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
}
EmojiFont::Draw(canvas, glyphs[i], x, y, paint);
// reset local index/count track for "real" glyphs
localCount = 0;
localIndex = i + 1;
} else {
pos[i].set(x, y);
localCount += 1;
}
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
// draw the last run of glyphs (if any)
if (localCount) {
rotator.mapPoints(&pos[localIndex], localCount);
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
}
if (font->platformData().orientation() == Vertical)
canvas->restore();
} else {
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
y += SkFloatToScalar(adv[i].height());
x += SkFloatToScalar(adv[i].width());
}
if (font->platformData().orientation() == Vertical) {
canvas->save();
canvas->rotate(-90);
SkMatrix rotator;
rotator.reset();
rotator.setRotate(90);
rotator.mapPoints(pos, numGlyphs);
}
canvas->drawPosText(glyphs,
numGlyphs * sizeof(uint16_t), pos, paint);
//.........这里部分代码省略.........
示例13: drawSVGGlyphs
void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const TextRun& run, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
SVGFontElement* fontElement = 0;
SVGFontFaceElement* fontFaceElement = 0;
const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
if (!fontElement || !fontFaceElement)
return;
// We can only paint SVGFonts if a context is available.
RenderSVGResource* activePaintingResource = activePaintingResourceFromRun(run);
RenderObject* renderObject = renderObjectFromRun(run);
RenderObject* parentRenderObject = firstParentRendererForNonTextNode(renderObject);
RenderStyle* parentRenderObjectStyle = 0;
ASSERT(renderObject);
if (!activePaintingResource) {
// TODO: We're only supporting simple filled HTML text so far.
RenderSVGResourceSolidColor* solidPaintingResource = RenderSVGResource::sharedSolidPaintingResource();
solidPaintingResource->setColor(context->fillColor());
activePaintingResource = solidPaintingResource;
}
bool isVerticalText = false;
if (parentRenderObject) {
parentRenderObjectStyle = parentRenderObject->style();
ASSERT(parentRenderObjectStyle);
isVerticalText = parentRenderObjectStyle->svgStyle()->isVerticalWritingMode();
}
float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
ASSERT(activePaintingResource);
FloatPoint glyphOrigin;
glyphOrigin.setX(svgFontData->horizontalOriginX() * scale);
glyphOrigin.setY(svgFontData->horizontalOriginY() * scale);
FloatPoint currentPoint = point;
RenderSVGResourceMode resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
for (int i = 0; i < numGlyphs; ++i) {
Glyph glyph = glyphBuffer.glyphAt(from + i);
if (!glyph)
continue;
float advance = glyphBuffer.advanceAt(from + i);
SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
ASSERT(!svgGlyph.isPartOfLigature);
ASSERT(svgGlyph.tableEntry == glyph);
SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, svgFontData);
// FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations).
if (svgGlyph.pathData.isEmpty()) {
if (isVerticalText)
currentPoint.move(0, advance);
else
currentPoint.move(advance, 0);
continue;
}
context->save();
if (isVerticalText) {
glyphOrigin.setX(svgGlyph.verticalOriginX * scale);
glyphOrigin.setY(svgGlyph.verticalOriginY * scale);
}
AffineTransform glyphPathTransform;
glyphPathTransform.translate(currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y());
glyphPathTransform.scale(scale, -scale);
Path glyphPath = svgGlyph.pathData;
glyphPath.transform(glyphPathTransform);
if (activePaintingResource->applyResource(parentRenderObject, parentRenderObjectStyle, context, resourceMode)) {
if (renderObject && renderObject->isSVGInlineText()) {
const RenderSVGInlineText* textRenderer = toRenderSVGInlineText(renderObject);
context->setStrokeThickness(context->strokeThickness() * textRenderer->scalingFactor());
}
activePaintingResource->postApplyResource(parentRenderObject, context, resourceMode, &glyphPath, 0);
}
context->restore();
if (isVerticalText)
currentPoint.move(0, advance);
else
currentPoint.move(advance, 0);
}
}
示例14: drawTextWithSpacing
void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point)
{
#if USE(WXGC)
wxGCDC* dc = static_cast<wxGCDC*>(graphicsContext->platformContext());
wxGraphicsContext* gc = dc->GetGraphicsContext();
gc->PushState();
cairo_t* cr = (cairo_t*)gc->GetNativeContext();
wxFont* wxfont = font->getWxFont();
cairo_scaled_font_t* scaled_font = 0;
#if wxUSE_PANGO
PangoFont* pangoFont = createPangoFontForFont(wxfont);
PangoFontMap* fontMap = pangoFontMap();
PangoContext* pangoContext = pango_cairo_font_map_create_context(PANGO_CAIRO_FONT_MAP(fontMap));
scaled_font = createScaledFontForFont(wxfont);
#elif __WXMSW__
cairo_matrix_t sizeMatrix, ctm;
cairo_matrix_init_identity(&ctm);
int size = font->platformData().size();
cairo_matrix_init_scale(&sizeMatrix, size, size);
cairo_font_options_t* fontOptions = cairo_font_options_create();
cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_SUBPIXEL);
cairo_font_face_t* win_face = cairo_win32_font_face_create_for_hfont((HFONT)wxfont->GetHFONT());
scaled_font = cairo_scaled_font_create(win_face, &sizeMatrix, &ctm, fontOptions);
#endif
ASSERT(scaled_font);
GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from));
float offset = point.x();
for (int i = 0; i < numGlyphs; i++) {
#if wxUSE_PANGO
glyphs[i].index = pango_font_get_glyph(pangoFont, pangoContext, glyphBuffer.glyphAt(from + i));
#endif
glyphs[i].x = offset;
glyphs[i].y = point.y();
offset += glyphBuffer.advanceAt(from + i);
}
cairo_set_source_rgba(cr, color.Red()/255.0, color.Green()/255.0, color.Blue()/255.0, color.Alpha()/255.0);
cairo_set_scaled_font(cr, scaled_font);
cairo_show_glyphs(cr, glyphs, numGlyphs);
cairo_scaled_font_destroy(scaled_font);
gc->PopState();
#else
wxDC* dc = graphicsContext->platformContext();
wxFont* wxfont = font->getWxFont();
if (wxfont && wxfont->IsOk())
dc->SetFont(*wxfont);
dc->SetTextForeground(color);
// convert glyphs to wxString
GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from));
int offset = point.x();
wxString text = wxEmptyString;
for (unsigned i = 0; i < numGlyphs; i++) {
text = text.Append((wxChar)glyphs[i]);
offset += glyphBuffer.advanceAt(from + i);
}
// the y point is actually the bottom point of the text, turn it into the top
float height = font->ascent() - font->descent();
wxCoord ypoint = (wxCoord) (point.y() - height);
dc->DrawText(text, (wxCoord)point.x(), ypoint);
#endif
}