本文整理汇总了C++中GlyphBuffer类的典型用法代码示例。如果您正苦于以下问题:C++ GlyphBuffer类的具体用法?C++ GlyphBuffer怎么用?C++ GlyphBuffer使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了GlyphBuffer类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: NOTIFY_PROCESS_STATUS
// We need to draw the glyphBuffer glyphs/advances with the pSimpleFontData font onto the
// pGraphicsContext pSurface. We draw glyphCount glyphs starting at the glyphIndexBegin.
void Font::drawGlyphs(GraphicsContext* pGraphicsContext, const SimpleFontData* pSimpleFontData, const GlyphBuffer& glyphBuffer,
int glyphIndexBegin, int glyphCount, const FloatPoint& point) const
{
// 11/09/09 CSidhall Added notify start of process to user
NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusStarted);
#if defined(EA_DEBUG) && defined(AUTHOR_PPEDRIANA_DISABLED) && defined(EA_PLATFORM_WINDOWS)
TraceGlyphBufferToString(pSimpleFontData, glyphBuffer, glyphIndexBegin, glyphCount, point);
#endif
GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(glyphIndexBegin));
float offset = 0;
int x_offset = 0;
EA::Internal::IFont* pFont = pSimpleFontData->m_font.mpFont;
EA::Internal::IGlyphCache* pGlyphCache = EA::WebKit::GetGlyphCache();
EAW_ASSERT_MSG(pGlyphCache, "GlyphCache is not set");
if(!pGlyphCache)
{
NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusEnded);
return;
}
EA::Internal::ITextureInfo* pTI = pGlyphCache->GetTextureInfo(0); // Right now we hard-code usage of what is the only texture.
EAW_ASSERT_MSG(pTI, "GlyphCache is not initialized with enough number of textures");
if(!pTI)
{
NOTIFY_PROCESS_STATUS(EA::WebKit::kVProcessTypeDrawGlyph, EA::WebKit::kVProcessStatusEnded);
return;
}
const int32_t textureSize = (int32_t)pTI->GetSize();
EA::Internal::IGlyphTextureInfo gti;
EA::Internal::GlyphMetrics glyphMetrics;
GlyphDrawInfoArray gdiArray((size_t)(unsigned)glyphCount);
// Walk through the list of glyphs and build up render info for each one.
for (int i = 0; i < glyphCount; i++)
{
EA::Internal::GlyphId g = glyphs[i];
if(!pFont->GetGlyphMetrics(g, glyphMetrics))
{
EAW_ASSERT_MSG(false, "Font::drawGlyphs: invalid glyph/Font combo.");
pFont->GetGlyphIds(L"?", 1, &g, true);
pFont->GetGlyphMetrics(g, glyphMetrics);
}
if(!pGlyphCache->GetGlyphTextureInfo(pFont, g, gti))
{
const EA::Internal::GlyphBitmap* pGlyphBitmap;
if(pFont->RenderGlyphBitmap(&pGlyphBitmap, g))
{
if(pGlyphCache->AddGlyphTexture(pFont, g, pGlyphBitmap->mpData, pGlyphBitmap->mnWidth, pGlyphBitmap->mnHeight,
pGlyphBitmap->mnStride, (uint32_t)pGlyphBitmap->mBitmapFormat, gti))
{
pGlyphCache->EndUpdate(gti.mpTextureInfo);
}
else
{
EAW_ASSERT_MSG(false, "Font::drawGlyphs: AddGlyphTexture failed.");
gti.mX1 = gti.mX2 = 0; // Make this an empty glyph. Normally this should never execute.
}
pFont->DoneGlyphBitmap(pGlyphBitmap);
}
else
{
EAW_ASSERT_MSG(false, "Font::drawGlyphs: invalid glyph/Font combo.");
gti.mX1 = gti.mX2 = 0; // Make this an empty glyph. Normally this should never execute.
}
}
// Apply kerning.
// Note by Paul Pedriana: Can we really apply kerning here at the render stage without it looking
// wrong? It seems to me this cannot work unless kerning is also taken into account at the
// layout stage. To do: See if in fact kerning is taken into account at the layout stage.
EA::Internal::Kerning kerning;
if((i > 0) && pFont->GetKerning(glyphs[i - 1], g, kerning, 0))
offset += kerning.mfKernX;
// The values we calculate here are relative to the current pen position at the
// baseline position of [xoffset, 0], where +X is rightward and +Y is upward.
gdiArray[i].x1 = (int)(offset + glyphMetrics.mfHBearingX);
gdiArray[i].x2 = (int)(offset + glyphMetrics.mfHBearingX + glyphMetrics.mfSizeX);
gdiArray[i].y1 = (int)(glyphMetrics.mfHBearingY);
gdiArray[i].y2 = (int)(glyphMetrics.mfHBearingY - glyphMetrics.mfSizeY);
gdiArray[i].tx = (int)(gti.mX1 * textureSize); // Convert [0..1] to [0..textureSize]
gdiArray[i].ty = (int)(gti.mY1 * textureSize);
// advanceAt should return a value that is usually equivalent to glyphMetrics.mfHAdvanceX, at least
// for most simple Western text. A case where it would be different would be Arabic combining glyphs,
// and custom kerning, though kerning adjustments are handled above.
offset += glyphBuffer.advanceAt(glyphIndexBegin + i);
// Free wrapper
if(gti.mpTextureInfo)
//.........这里部分代码省略.........
示例2: SkFloatToScalar
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
const FloatPoint& point, const FloatRect& textRect) const
{
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
const OpenTypeVerticalData* verticalData = font->verticalData();
if (font->platformData().orientation() == Vertical && verticalData) {
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
AffineTransform savedMatrix = gc->getCTM();
gc->concatCTM(AffineTransform(0, -1, 1, 0, point.x(), point.y()));
gc->concatCTM(AffineTransform(1, 0, 0, 1, -point.x(), -point.y()));
const unsigned kMaxBufferLength = 256;
Vector<FloatPoint, kMaxBufferLength> translations;
const FontMetrics& metrics = font->fontMetrics();
SkScalar verticalOriginX = SkFloatToScalar(point.x() + metrics.floatAscent() - metrics.floatAscent(IdeographicBaseline));
float horizontalOffset = point.x();
unsigned glyphIndex = 0;
while (glyphIndex < numGlyphs) {
unsigned chunkLength = std::min(kMaxBufferLength, numGlyphs - glyphIndex);
const Glyph* glyphs = glyphBuffer.glyphs(from + glyphIndex);
translations.resize(chunkLength);
verticalData->getVerticalTranslationsForGlyphs(font, &glyphs[0], chunkLength, reinterpret_cast<float*>(&translations[0]));
x = verticalOriginX;
y = SkFloatToScalar(point.y() + horizontalOffset - point.x());
float currentWidth = 0;
for (unsigned i = 0; i < chunkLength; ++i, ++glyphIndex) {
pos[i].set(
x + SkIntToScalar(lroundf(translations[i].x())),
y + -SkIntToScalar(-lroundf(currentWidth - translations[i].y())));
currentWidth += glyphBuffer.advanceAt(from + glyphIndex);
}
horizontalOffset += currentWidth;
paintGlyphs(gc, font, glyphs, chunkLength, pos, textRect);
}
gc->setCTM(savedMatrix);
return;
}
if (!glyphBuffer.hasOffsets()) {
SkAutoSTMalloc<64, SkScalar> storage(numGlyphs);
SkScalar* xpos = storage.get();
const float* adv = glyphBuffer.advances(from);
for (unsigned i = 0; i < numGlyphs; i++) {
xpos[i] = x;
x += SkFloatToScalar(adv[i]);
}
const Glyph* glyphs = glyphBuffer.glyphs(from);
paintGlyphsHorizontal(gc, font, glyphs, numGlyphs, xpos, SkFloatToScalar(y), textRect);
return;
}
// FIXME: text rendering speed:
// Android has code in their WebCore fork to special case when the
// GlyphBuffer has no advances other than the defaults. In that case the
// text drawing can proceed faster. However, it's unclear when those
// patches may be upstreamed to WebKit so we always use the slower path
// here.
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
const FloatSize* offsets = glyphBuffer.offsets(from);
const float* advances = glyphBuffer.advances(from);
SkScalar advanceSoFar = SkFloatToScalar(0);
for (unsigned i = 0; i < numGlyphs; i++) {
pos[i].set(
x + SkFloatToScalar(offsets[i].width()) + advanceSoFar,
y + SkFloatToScalar(offsets[i].height()));
advanceSoFar += SkFloatToScalar(advances[i]);
}
const Glyph* glyphs = glyphBuffer.glyphs(from);
paintGlyphs(gc, font, glyphs, numGlyphs, pos, textRect);
}
示例3: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
switch(fontDescription().fontSmoothing()) {
case Antialiased: {
graphicsContext->setShouldAntialias(true);
shouldUseFontSmoothing = false;
break;
}
case SubpixelAntialiased: {
graphicsContext->setShouldAntialias(true);
shouldUseFontSmoothing = true;
break;
}
case NoSmoothing: {
graphicsContext->setShouldAntialias(false);
shouldUseFontSmoothing = false;
break;
}
case AutoSmoothing: {
// For the AutoSmooth case, don't do anything! Keep the default settings.
break;
}
default:
ASSERT_NOT_REACHED();
}
if (font->platformData().useGDI() && !shouldUseFontSmoothing) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext, shouldUseFontSmoothing);
const FontPlatformData& platformData = font->platformData();
CGContextSetFont(cgContext, platformData.cgFont());
CGAffineTransform matrix = CGAffineTransformIdentity;
matrix.b = -matrix.b;
matrix.d = -matrix.d;
if (platformData.syntheticOblique()) {
static float skew = -tanf(syntheticObliqueAngle * piFloat / 180.0f);
matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
}
CGContextSetTextMatrix(cgContext, matrix);
// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
CGContextSetFontSize(cgContext, platformData.size());
wkSetCGContextFontRenderingStyle(cgContext, font->isSystemFont(), false, font->platformData().useGDI());
FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
ColorSpace shadowColorSpace;
graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
bool hasSimpleShadow = graphicsContext->textDrawingMode() == TextModeFill && shadowColor.isValid() && !shadowBlur && (!graphicsContext->shadowsIgnoreTransforms() || graphicsContext->getCTM().isIdentityOrTranslationOrFlipped());
if (hasSimpleShadow) {
// Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
graphicsContext->clearShadow();
Color fillColor = graphicsContext->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
graphicsContext->setFillColor(shadowFillColor, ColorSpaceDeviceRGB);
float shadowTextX = point.x() + translation.width() + shadowOffset.width();
// If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
float shadowTextY = point.y() + translation.height() + shadowOffset.height() * (graphicsContext->shadowsIgnoreTransforms() ? -1 : 1);
CGContextSetTextPosition(cgContext, shadowTextX, shadowTextY);
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowOffset.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor, ColorSpaceDeviceRGB);
}
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->syntheticBoldOffset(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
if (hasSimpleShadow)
graphicsContext->setShadow(shadowOffset, shadowBlur, shadowColor, ColorSpaceDeviceRGB);
wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
}
示例4: SkASSERT
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));
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);
SkPoint* pos = storage.get();
SkCanvas* canvas = gc->platformContext()->mCanvas;
/* 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 (EmojiFont::IsAvailable()) {
// set filtering, to make scaled images look nice(r)
paint.setFilterBitmap(true);
int localIndex = 0;
int localCount = 0;
for (int i = 0; i < numGlyphs; i++) {
if (EmojiFont::IsEmojiGlyph(glyphs[i])) {
if (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)
canvas->drawPosText(&glyphs[localIndex],
localCount * sizeof(uint16_t),
&pos[localIndex], paint);
} else {
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
x += SkFloatToScalar(adv[i].width());
y += SkFloatToScalar(adv[i].height());
}
canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
}
}
示例5: TEST
TEST(GlyphBufferTest, StartsEmpty) {
GlyphBuffer glyphBuffer;
EXPECT_TRUE(glyphBuffer.isEmpty());
EXPECT_EQ(0u, glyphBuffer.size());
}
示例6: drawTextWithSpacing
void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* font, const wxColour& color, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point)
{
graphicsContext->save();
wxGCDC* dc = static_cast<wxGCDC*>(graphicsContext->platformContext());
wxFont* wxfont = font->getWxFont();
graphicsContext->setFillColor(graphicsContext->fillColor(), DeviceColorSpace);
CGContextRef cgContext = static_cast<CGContextRef>(dc->GetGraphicsContext()->GetNativeContext());
CGFontRef cgFont;
#ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
cgFont = CTFontCopyGraphicsFont((CTFontRef)wxfont->OSXGetCTFont(), NULL);
#else
ATSFontRef fontRef;
fontRef = FMGetATSFontRefFromFont(wxfont->MacGetATSUFontID());
if (fontRef)
cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
#endif
CGContextSetFont(cgContext, cgFont);
CGContextSetFontSize(cgContext, wxfont->GetPointSize());
CGFloat red, green, blue, alpha;
graphicsContext->fillColor().getRGBA(red, green, blue, alpha);
CGContextSetRGBFillColor(cgContext, red, green, blue, alpha);
CGAffineTransform matrix = CGAffineTransformIdentity;
matrix.b = -matrix.b;
matrix.d = -matrix.d;
CGContextSetTextMatrix(cgContext, matrix);
CGContextSetTextPosition(cgContext, point.x(), point.y());
const FloatSize* advanceSizes = static_cast<const FloatSize*>(glyphBuffer.advances(from));
int size = glyphBuffer.size() - from;
CGSize sizes[size];
CGGlyph glyphs[numGlyphs];
// if the function doesn't exist, we're probably on tiger and need to grab the
// function under its old name, CGFontGetGlyphsForUnicodes
if (!CGFontGetGlyphsForUnichars)
CGFontGetGlyphsForUnichars = (CGFontGetGlyphsForUnicharsPtr)dlsym(RTLD_DEFAULT, "CGFontGetGlyphsForUnicodes");
// Let's make sure we got the function under one name or another!
ASSERT(CGFontGetGlyphsForUnichars);
CGFontGetGlyphsForUnichars(cgFont, glyphBuffer.glyphs(from), glyphs, numGlyphs);
for (int i = 0; i < size; i++) {
FloatSize fsize = advanceSizes[i];
sizes[i] = CGSizeMake(fsize.width(), fsize.height());
}
CGContextShowGlyphsWithAdvances(cgContext, glyphs, sizes, numGlyphs);
if (cgFont)
CGFontRelease(cgFont);
graphicsContext->restore();
}
示例7: SkASSERT
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);
//.........这里部分代码省略.........
示例8: 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);
}
}
示例9: drawGlyphs
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
CGContextRef cgContext = graphicsContext->platformContext();
bool shouldUseFontSmoothing = WebCoreShouldUseFontSmoothing();
if (font->platformData().useGDI()) {
static bool canUsePlatformNativeGlyphs = wkCanUsePlatformNativeGlyphs();
if (!canUsePlatformNativeGlyphs || !shouldUseFontSmoothing || (graphicsContext->textDrawingMode() & cTextStroke)) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}
}
uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext, shouldUseFontSmoothing);
const FontPlatformData& platformData = font->platformData();
CGContextSetFont(cgContext, platformData.cgFont());
CGAffineTransform matrix = CGAffineTransformIdentity;
matrix.b = -matrix.b;
matrix.d = -matrix.d;
if (platformData.syntheticOblique()) {
static float skew = -tanf(syntheticObliqueAngle * piFloat / 180.0f);
matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, skew, 1, 0, 0));
}
CGContextSetTextMatrix(cgContext, matrix);
// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
CGContextSetFontSize(cgContext, platformData.size());
wkSetCGContextFontRenderingStyle(cgContext, font->isSystemFont(), false, font->platformData().useGDI());
IntSize shadowSize;
int shadowBlur;
Color shadowColor;
graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor);
bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur;
if (hasSimpleShadow) {
// Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
graphicsContext->clearShadow();
Color fillColor = graphicsContext->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
graphicsContext->setFillColor(shadowFillColor);
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width(), point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->m_syntheticBoldOffset) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->m_syntheticBoldOffset, point.y() + translation.height() + shadowSize.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor);
}
CGContextSetTextPosition(cgContext, point.x() + translation.width(), point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->m_syntheticBoldOffset) {
CGContextSetTextPosition(cgContext, point.x() + translation.width() + font->m_syntheticBoldOffset, point.y() + translation.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
if (hasSimpleShadow)
graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor);
wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
}
示例10: drawglyphs
static void drawglyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point, float height, float ascent,
uint32 penalpha, uint32 penr, uint32 peng, uint32 penb, int shadowx, int shadowy)
{
GlyphBufferGlyph* glyphs = const_cast<GlyphBufferGlyph*>(glyphBuffer.glyphs(from));
struct OutlineFont *face = font->m_platformData.m_face;
uint32 ysize = font->m_platformData.m_size;
int32 imagewidth = 0;
uint32 onlyspaces = TRUE;
for (int i = 0; i < numGlyphs; i++) {
if (32 != glyphs[i])
onlyspaces = FALSE;
imagewidth += glyphBuffer.advanceAt(from + i);
}
if (onlyspaces)
return;
if (imagewidth <= 0)
return;
imagewidth += 2 * (ysize * amigaConfig.fontXDPI / 72);
Vector<unsigned> *glyphRGBABuffer = new Vector<unsigned>(imagewidth * height);
if (!glyphRGBABuffer)
return;
glyphRGBABuffer->fill(0);
int32 offsetinimg = 0;
uint32 shiftleft = 0;
for (int i = 0; i < numGlyphs; i++) {
if (32 == glyphs[i]) {
offsetinimg += glyphBuffer.advanceAt(from + i);
continue;
}
struct GlyphMap *glyph;
if (IDiskfont->ESetInfo(&face->olf_EEngine,
OT_GlyphCode, glyphs[i],
TAG_END))
continue; //do not handle error
struct OutlineFont *curface = face;
if (IDiskfont->EObtainInfo(&face->olf_EEngine,
OT_GlyphMap8Bit, &glyph,
TAG_END)) {
uint32 ok = FALSE;
if (amigaConfig.unicodeFace
&& !IDiskfont->ESetInfo(&amigaConfig.unicodeFace->olf_EEngine,
OT_PointHeight, ysize << 16,
OT_GlyphCode, glyphs[i],
TAG_END)
&& !IDiskfont->EObtainInfo(&amigaConfig.unicodeFace->olf_EEngine,
OT_GlyphMap8Bit, &glyph,
TAG_END)) {
curface = amigaConfig.unicodeFace;
ok = TRUE;
}
if (!ok
&& !IDiskfont->ESetInfo(&face->olf_EEngine,
OT_GlyphCode, 0xFFFD,
TAG_END)
&& !IDiskfont->EObtainInfo(&face->olf_EEngine,
OT_GlyphMap8Bit, &glyph,
TAG_END))
ok = TRUE;
if (!ok
&& !IDiskfont->ESetInfo(&face->olf_EEngine,
OT_GlyphCode, '?',
TAG_END)
&& !IDiskfont->EObtainInfo(&face->olf_EEngine,
OT_GlyphMap8Bit, &glyph,
TAG_END))
ok = TRUE;
if (!ok)
continue; //do not handle error
}
if (amigaConfig.fontKerning && i > 0)
if (!IDiskfont->ESetInfo(&curface->olf_EEngine,
OT_GlyphCode, glyphs[i -1],
OT_GlyphCode2, glyphs[i],
TAG_END)) {
FIXED kern = 0;
if (!IDiskfont->EObtainInfo(&curface->olf_EEngine,
OT_TextKernPair, &kern,
TAG_END))
if (kern)
offsetinimg -= (int)(kern / 65536.0 * ysize * amigaConfig.fontYDPI / 72);
}
uint32 left = glyph->glm_BlackLeft;
//.........这里部分代码省略.........
示例11: drawGlyphs
void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
TextRun run(glyphBuffer.glyphs(from), numGlyphs, false, 0, 0, false, false, false, false);
drawComplexText(context, run, point, 0, numGlyphs);
}
示例12: drawGDIGlyphs
static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point)
{
Color fillColor = graphicsContext->fillColor();
bool drawIntoBitmap = false;
TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode();
if (drawingMode == TextModeFill) {
if (!fillColor.alpha())
return;
drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer();
if (!drawIntoBitmap) {
FloatSize offset;
float blur;
Color color;
ColorSpace shadowColorSpace;
graphicsContext->getShadow(offset, blur, color, shadowColorSpace);
drawIntoBitmap = offset.width() || offset.height() || blur;
}
}
// We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
Vector<int, 2048> gdiAdvances;
int totalWidth = 0;
for (int i = 0; i < numGlyphs; i++) {
gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
totalWidth += gdiAdvances[i];
}
HDC hdc = 0;
OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
IntRect textRect;
if (!drawIntoBitmap)
hdc = graphicsContext->getWindowsContext(textRect, true, false);
if (!hdc) {
drawIntoBitmap = true;
// We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
// FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
const FontMetrics& fontMetrics = font->fontMetrics();
int lineGap = fontMetrics.lineGap();
textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
point.y() - fontMetrics.ascent() - lineGap,
totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
fontMetrics.lineSpacing());
bitmap = graphicsContext->createWindowsBitmap(textRect.size());
memset(bitmap->buffer(), 255, bitmap->bufferLength());
hdc = bitmap->hdc();
XFORM xform;
xform.eM11 = 1.0f;
xform.eM12 = 0.0f;
xform.eM21 = 0.0f;
xform.eM22 = 1.0f;
xform.eDx = -textRect.x();
xform.eDy = -textRect.y();
SetWorldTransform(hdc, &xform);
}
SelectObject(hdc, font->platformData().hfont());
// Set the correct color.
if (drawIntoBitmap)
SetTextColor(hdc, RGB(0, 0, 0));
else
SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
SetBkMode(hdc, TRANSPARENT);
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());
//.........这里部分代码省略.........
示例13: offsetToMiddleOfAdvanceAtIndex
inline static float offsetToMiddleOfAdvanceAtIndex(const GlyphBuffer& glyphBuffer, size_t i)
{
return glyphBuffer.advanceAt(i) / 2;
}
示例14: COMPILE_ASSERT
// TODO: This needs to be split into helper functions to better scope the
// inputs/outputs, and reduce duplicate code.
// This issue is tracked in https://bugs.webkit.org/show_bug.cgi?id=62989
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
COMPILE_ASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t), GlyphBufferGlyphSize_equals_uint16_t);
bool shouldSmoothFonts = true;
bool shouldAntialias = true;
switch (fontDescription().fontSmoothing()) {
case Antialiased:
shouldSmoothFonts = false;
break;
case SubpixelAntialiased:
break;
case NoSmoothing:
shouldAntialias = false;
shouldSmoothFonts = false;
break;
case AutoSmoothing:
// For the AutoSmooth case, don't do anything! Keep the default settings.
break;
}
if (!shouldUseSmoothing() || PlatformSupport::layoutTestMode())
shouldSmoothFonts = false;
const GlyphBufferGlyph* glyphs = glyphBuffer.glyphs(from);
SkScalar x = SkFloatToScalar(point.x());
SkScalar y = SkFloatToScalar(point.y());
if (font->platformData().orientation() == Vertical)
y += SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
// FIXME: text rendering speed:
// Android has code in their WebCore fork to special case when the
// GlyphBuffer has no advances other than the defaults. In that case the
// text drawing can proceed faster. However, it's unclear when those
// patches may be upstreamed to WebKit so we always use the slower path
// here.
const GlyphBufferAdvance* adv = glyphBuffer.advances(from);
SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
SkPoint* pos = storage.get();
for (int i = 0; i < numGlyphs; i++) {
pos[i].set(x, y);
x += SkFloatToScalar(adv[i].width);
y += SkFloatToScalar(adv[i].height);
}
SkCanvas* canvas = gc->platformContext()->canvas();
if (font->platformData().orientation() == Vertical) {
canvas->save();
canvas->rotate(-90);
SkMatrix rotator;
rotator.reset();
rotator.setRotate(90);
rotator.mapPoints(pos, numGlyphs);
}
TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode();
// We draw text up to two times (once for fill, once for stroke).
if (textMode & TextModeFill) {
SkPaint paint;
gc->platformContext()->setupPaintForFilling(&paint);
setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts);
gc->platformContext()->adjustTextRenderMode(&paint);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
}
if ((textMode & TextModeStroke)
&& gc->platformContext()->getStrokeStyle() != NoStroke
&& gc->platformContext()->getStrokeThickness() > 0) {
SkPaint paint;
gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts);
gc->platformContext()->adjustTextRenderMode(&paint);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
if (textMode & TextModeFill) {
// If we also filled, we don't want to draw shadows twice.
// See comment in FontChromiumWin.cpp::paintSkiaText() for more details.
paint.setLooper(0);
}
canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint);
}
if (font->platformData().orientation() == Vertical)
canvas->restore();
}
示例15: 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;
}
}