本文整理汇总了C++中AffineTransform类的典型用法代码示例。如果您正苦于以下问题:C++ AffineTransform类的具体用法?C++ AffineTransform怎么用?C++ AffineTransform使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AffineTransform类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: drawImage
void LowLevelGraphicsPostScriptRenderer::drawImage (const Image& sourceImage, const AffineTransform& transform)
{
const int w = sourceImage.getWidth();
const int h = sourceImage.getHeight();
writeClip();
out << "gsave ";
writeTransform (transform.translated ((float) stateStack.getLast()->xOffset, (float) stateStack.getLast()->yOffset)
.scaled (1.0f, -1.0f));
RectangleList<int> imageClip;
sourceImage.createSolidAreaMask (imageClip, 0.5f);
out << "newpath ";
int itemsOnLine = 0;
for (const Rectangle<int>* i = imageClip.begin(), * const e = imageClip.end(); i != e; ++i)
{
if (++itemsOnLine == 6)
{
out << '\n';
itemsOnLine = 0;
}
out << i->getX() << ' ' << i->getY() << ' ' << i->getWidth() << ' ' << i->getHeight() << " pr ";
}
out << " clip newpath\n";
out << w << ' ' << h << " scale\n";
out << w << ' ' << h << " 8 [" << w << " 0 0 -" << h << ' ' << (int) 0 << ' ' << h << " ]\n";
writeImage (sourceImage, 0, 0, w, h);
out << "false 3 colorimage grestore\n";
needToClip = true;
}
示例2: TEST
TEST(TransparencyWin, DISABLED_TranslateScaleOpaqueCompositeLayer)
{
OwnPtr<ImageBuffer> src(ImageBuffer::create(IntSize(16, 16), 1));
// The background is white on top with red on bottom.
Color white(0xFFFFFFFF);
FloatRect topRect(0, 0, 16, 8);
src->context()->fillRect(topRect, white);
Color red(0xFFFF0000);
FloatRect bottomRect(0, 8, 16, 8);
src->context()->fillRect(bottomRect, red);
src->context()->save();
// Translate left by one pixel.
AffineTransform left;
left.translate(-1, 0);
// Scale by 2x.
AffineTransform scale;
scale.scale(2.0);
src->context()->concatCTM(scale);
// Then translate up by one pixel (which will actually be 2 due to scaling).
AffineTransform up;
up.translate(0, -1);
src->context()->concatCTM(up);
// Now draw 50% red square.
{
// Create a transparency helper inset one pixel in the buffer. The
// coordinates are before transforming into this space, and maps to
// IntRect(1, 1, 14, 14).
TransparencyWin helper;
helper.init(src->context(),
TransparencyWin::OpaqueCompositeLayer,
TransparencyWin::KeepTransform,
IntRect(1, -15, 14, 14));
// Fill with red.
helper.context()->fillRect(helper.drawRect(), Color(0x7f7f0000));
clearTopLayerAlphaChannel(helper.context());
helper.composite();
}
}
示例3: ASSERT
PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes,
const FloatRect& tileBoundaries,
const FloatRect& absoluteTileBoundaries,
const AffineTransform& tileImageTransform,
FloatRect& clampedAbsoluteTileBoundaries) const
{
clampedAbsoluteTileBoundaries = SVGImageBufferTools::clampedAbsoluteTargetRect(absoluteTileBoundaries);
OwnPtr<ImageBuffer> tileImage;
if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB))
return nullptr;
GraphicsContext* tileImageContext = tileImage->context();
ASSERT(tileImageContext);
// The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
tileImageContext->scale(FloatSize(clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(),
clampedAbsoluteTileBoundaries.height() / tileBoundaries.height()));
// Apply tile image transformations.
if (!tileImageTransform.isIdentity())
tileImageContext->concatCTM(tileImageTransform);
AffineTransform contentTransformation;
if (attributes.boundingBoxModeContent())
contentTransformation = tileImageTransform;
// Draw the content into the ImageBuffer.
for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
continue;
SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation);
}
return tileImage.release();
}
示例4: blend
void AffineTransform::blend(const AffineTransform& from, double progress)
{
DecomposedType srA, srB;
from.decompose(srA);
this->decompose(srB);
// If x-axis of one is flipped, and y-axis of the other, convert to an unflipped rotation.
if ((srA.scaleX < 0 && srB.scaleY < 0) || (srA.scaleY < 0 && srB.scaleX < 0)) {
srA.scaleX = -srA.scaleX;
srA.scaleY = -srA.scaleY;
srA.angle += srA.angle < 0 ? piDouble : -piDouble;
}
// Don't rotate the long way around.
srA.angle = fmod(srA.angle, 2 * piDouble);
srB.angle = fmod(srB.angle, 2 * piDouble);
if (fabs(srA.angle - srB.angle) > piDouble) {
if (srA.angle > srB.angle)
srA.angle -= piDouble * 2;
else
srB.angle -= piDouble * 2;
}
srA.scaleX += progress * (srB.scaleX - srA.scaleX);
srA.scaleY += progress * (srB.scaleY - srA.scaleY);
srA.angle += progress * (srB.angle - srA.angle);
srA.remainderA += progress * (srB.remainderA - srA.remainderA);
srA.remainderB += progress * (srB.remainderB - srA.remainderB);
srA.remainderC += progress * (srB.remainderC - srA.remainderC);
srA.remainderD += progress * (srB.remainderD - srA.remainderD);
srA.translateX += progress * (srB.translateX - srA.translateX);
srA.translateY += progress * (srB.translateY - srA.translateY);
this->recompose(srA);
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_external_chromium_org_third_party_WebKit,代码行数:37,代码来源:AffineTransform.cpp
示例5: rotationOfCharacterCallback
static bool rotationOfCharacterCallback(QueryData* queryData, const SVGTextFragment& fragment)
{
RotationOfCharacterData* data = static_cast<RotationOfCharacterData*>(queryData);
int startPosition = data->position;
int endPosition = startPosition + 1;
if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
return false;
if (!fragment.isTransformed()) {
data->rotation = 0;
} else {
AffineTransform fragmentTransform = fragment.buildFragmentTransform(SVGTextFragment::TransformIgnoringTextLength);
fragmentTransform.scale(1 / fragmentTransform.xScale(), 1 / fragmentTransform.yScale());
data->rotation = narrowPrecisionToFloat(rad2deg(atan2(fragmentTransform.b(), fragmentTransform.a())));
}
return true;
}
示例6: drawImage
void drawImage (const Image& image, const AffineTransform& transform)
{
renderingTarget->SetTransform (transformToMatrix (transform.followedBy (currentState->transform)));
D2D1_SIZE_U size;
size.width = image.getWidth();
size.height = image.getHeight();
D2D1_BITMAP_PROPERTIES bp = D2D1::BitmapProperties();
Image img (image.convertedToFormat (Image::ARGB));
Image::BitmapData bd (img, Image::BitmapData::readOnly);
bp.pixelFormat = renderingTarget->GetPixelFormat();
bp.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;
{
ComSmartPtr <ID2D1Bitmap> tempBitmap;
renderingTarget->CreateBitmap (size, bd.data, bd.lineStride, bp, tempBitmap.resetAndGetPointerAddress());
if (tempBitmap != nullptr)
renderingTarget->DrawBitmap (tempBitmap);
}
renderingTarget->SetTransform (D2D1::IdentityMatrix());
}
示例7: drawPattern
void Image::drawPattern(GraphicsContext *gc, const FloatRect& srcRect, const AffineTransform& patternTransform,
const FloatPoint& phase, ColorSpace, CompositeOperator, const FloatRect& destRect, BlendMode)
{
JNIEnv* env = WebCore_GetJavaEnv();
if (!gc || gc->paintingDisabled() || srcRect.isEmpty()) {
return;
}
NativeImagePtr currFrame = nativeImageForCurrentFrame();
if (!currFrame) {
return;
}
TransformationMatrix tm = patternTransform.toTransformationMatrix();
static jmethodID mid = env->GetMethodID(PG_GetGraphicsManagerClass(env),
"createTransform",
"(DDDDDD)Lcom/sun/webkit/graphics/WCTransform;");
ASSERT(mid);
JLObject transform(env->CallObjectMethod(PL_GetGraphicsManager(env), mid,
tm.a(), tm.b(), tm.c(), tm.d(), tm.e(), tm.f()));
ASSERT(transform);
CheckAndClearException(env);
gc->platformContext()->rq().freeSpace(13 * 4)
<< (jint)com_sun_webkit_graphics_GraphicsDecoder_DRAWPATTERN
<< currFrame
<< srcRect.x() << srcRect.y() << srcRect.width() << srcRect.height()
<< RQRef::create(transform)
<< phase.x() << phase.y()
<< destRect.x() << destRect.y() << destRect.width() << destRect.height();
if (imageObserver())
imageObserver()->didDraw(this);
}
示例8: affineTransformToSkMatrix
SkMatrix affineTransformToSkMatrix(const AffineTransform& source)
{
SkMatrix result;
result.setScaleX(WebCoreDoubleToSkScalar(source.a()));
result.setSkewX(WebCoreDoubleToSkScalar(source.c()));
result.setTranslateX(WebCoreDoubleToSkScalar(source.e()));
result.setScaleY(WebCoreDoubleToSkScalar(source.d()));
result.setSkewY(WebCoreDoubleToSkScalar(source.b()));
result.setTranslateY(WebCoreDoubleToSkScalar(source.f()));
// FIXME: Set perspective properly.
result.setPerspX(0);
result.setPerspY(0);
result.set(SkMatrix::kMPersp2, SK_Scalar1);
return result;
}
示例9:
// static
void Shader::affineTo4x4(const AffineTransform& transform, float mat[16])
{
mat[0] = transform.a();
mat[1] = transform.b();
mat[2] = 0.0f;
mat[3] = 0.0f;
mat[4] = transform.c();
mat[5] = transform.d();
mat[6] = 0.0f;
mat[7] = 0.0f;
mat[8] = 0.0f;
mat[9] = 0.0f;
mat[10] = 1.0f;
mat[11] = 0.0f;
mat[12] = transform.e();
mat[13] = transform.f();
mat[14] = 0.0f;
mat[15] = 1.0f;
}
示例10: getTransform
AffineTransform getTransform()
{
const float hw = 0.5f * getWidth();
const float hh = 0.5f * getHeight();
AffineTransform t;
if (controls.animateRotation.getToggleState())
t = t.rotated (rotation.getValue() * float_Pi * 2.0f);
if (controls.animateSize.getToggleState())
t = t.scaled (0.3f + size.getValue() * 2.0f);
if (controls.animatePosition.getToggleState())
t = t.translated (hw + hw * (offsetX.getValue() - 0.5f),
hh + hh * (offsetY.getValue() - 0.5f));
else
t = t.translated (hw, hh);
if (controls.animateShear.getToggleState())
t = t.sheared (shear.getValue() * 2.0f - 1.0f, 0.0f);
return t;
}
示例11: svgFontAndFontFaceElementForFontData
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);
}
}
示例12: calculateMaskContentRepaintRect
void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
{
FloatRect objectBoundingBox = object->objectBoundingBox();
// Mask rect clipped with clippingBoundingBox and filterBoundingBox as long as they are present.
maskerData->maskRect = object->repaintRectInLocalCoordinates();
if (maskerData->maskRect.isEmpty()) {
maskerData->emptyMask = true;
return;
}
if (m_maskBoundaries.isEmpty())
calculateMaskContentRepaintRect();
FloatRect repaintRect = m_maskBoundaries;
AffineTransform contextTransform;
// We need to scale repaintRect for objectBoundingBox to get the drawing area.
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
FloatPoint contextAdjustment = repaintRect.location();
repaintRect = contextTransform.mapRect(repaintRect);
repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y());
contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y());
}
repaintRect.intersect(maskerData->maskRect);
maskerData->maskRect = repaintRect;
IntRect maskImageRect = enclosingIntRect(maskerData->maskRect);
maskImageRect.setLocation(IntPoint());
// Don't create ImageBuffers with image size of 0
if (maskImageRect.isEmpty()) {
maskerData->emptyMask = true;
return;
}
// FIXME: This changes color space to linearRGB, the default color space
// for masking operations in SVG. We need a switch for the other color-space
// attribute values sRGB, inherit and auto.
maskerData->maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB);
if (!maskerData->maskImage)
return;
GraphicsContext* maskImageContext = maskerData->maskImage->context();
ASSERT(maskImageContext);
maskImageContext->save();
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
maskImageContext->translate(-maskerData->maskRect.x(), -maskerData->maskRect.y());
maskImageContext->concatCTM(contextTransform);
// draw the content into the ImageBuffer
for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
RenderObject* renderer = node->renderer();
if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
renderSubtreeToImage(maskerData->maskImage.get(), renderer);
}
maskImageContext->restore();
// create the luminance mask
RefPtr<ImageData> imageData(maskerData->maskImage->getUnmultipliedImageData(maskImageRect));
CanvasPixelArray* srcPixelArray(imageData->data());
for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset += 4) {
unsigned char a = srcPixelArray->get(pixelOffset + 3);
if (!a)
continue;
unsigned char r = srcPixelArray->get(pixelOffset);
unsigned char g = srcPixelArray->get(pixelOffset + 1);
unsigned char b = srcPixelArray->get(pixelOffset + 2);
double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0);
srcPixelArray->set(pixelOffset + 3, luma);
}
maskerData->maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint());
}
示例13: calculateTransformationToOutermostCoordinateSystem
float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject& renderer)
{
AffineTransform ctm = calculateTransformationToOutermostCoordinateSystem(renderer);
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
}
示例14: switch
// DragTo
void
DragSideState::DragTo(BPoint current, uint32 modifiers)
{
BRect oldBox = fParent->Box();
if (oldBox.Width() == 0.0 || oldBox.Height() == 0.0)
return;
// TODO: some of this can be combined into less steps
BRect newBox = oldBox;
fOldTransform.InverseTransform(¤t);
switch (fSide) {
case LEFT_SIDE:
newBox.left = current.x - fOffsetFromSide;
break;
case RIGHT_SIDE:
newBox.right = current.x - fOffsetFromSide;
break;
case TOP_SIDE:
newBox.top = current.y - fOffsetFromSide;
break;
case BOTTOM_SIDE:
newBox.bottom = current.y - fOffsetFromSide;
break;
}
if (!(modifiers & B_SHIFT_KEY)) {
// keep the x and y scale the same
double xScale = newBox.Width() / oldBox.Width();
double yScale = newBox.Height() / oldBox.Height();
if (modifiers & B_COMMAND_KEY) {
xScale = snap_scale(xScale);
yScale = snap_scale(yScale);
}
if (fSide == LEFT_SIDE || fSide == RIGHT_SIDE)
yScale = yScale > 0.0 ? fabs(xScale) : -fabs(xScale);
else
xScale = xScale > 0.0 ? fabs(yScale) : -fabs(yScale);
switch (fSide) {
case LEFT_SIDE: {
newBox.left = oldBox.right - oldBox.Width() * xScale;
float middle = (oldBox.top + oldBox.bottom) / 2.0;
float newHeight = oldBox.Height() * yScale;
newBox.top = middle - newHeight / 2.0;
newBox.bottom = middle + newHeight / 2.0;
break;
}
case RIGHT_SIDE: {
newBox.right = oldBox.left + oldBox.Width() * xScale;
float middle = (oldBox.top + oldBox.bottom) / 2.0;
float newHeight = oldBox.Height() * yScale;
newBox.top = middle - newHeight / 2.0;
newBox.bottom = middle + newHeight / 2.0;
break;
}
case TOP_SIDE: {
newBox.top = oldBox.bottom - oldBox.Height() * yScale;
float middle = (oldBox.left + oldBox.right) / 2.0;
float newWidth = oldBox.Width() * xScale;
newBox.left = middle - newWidth / 2.0;
newBox.right = middle + newWidth / 2.0;
break;
}
case BOTTOM_SIDE: {
newBox.bottom = oldBox.top + oldBox.Height() * yScale;
float middle = (oldBox.left + oldBox.right) / 2.0;
float newWidth = oldBox.Width() * xScale;
newBox.left = middle - newWidth / 2.0;
newBox.right = middle + newWidth / 2.0;
break;
}
}
}
// build a matrix that performs just the
// distortion of the box with the opposite
// corner of the one being dragged staying fixed
AffineTransform s;
s.rect_to_rect(oldBox.left, oldBox.top, oldBox.right, oldBox.bottom,
newBox.left, newBox.top, newBox.right, newBox.bottom);
// construct a transformation that
// * excludes the effect of the fParant->Pivot()
// * includes the effect of the changed scaling and translation
// (see DragCornerState::DragTo() for explaination)
AffineTransform t;
BPoint pivot(fParent->Pivot());
t.TranslateBy(pivot.x, pivot.y);
t.Multiply(s);
t.Multiply(fOldTransform);
t.TranslateBy(-pivot.x, -pivot.y);
//.........这里部分代码省略.........
示例15: ASSERT
void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(truncation() == cNoTruncation);
if (renderer()->style()->visibility() != VISIBLE)
return;
// Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox.
// If we ever need that for SVG, it's very easy to refactor and reuse the code.
RenderObject* parentRenderer = parent()->renderer();
ASSERT(parentRenderer);
bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
bool hasSelection = !parentRenderer->document().printing() && selectionState() != RenderObject::SelectionNone;
if (!hasSelection && paintSelectedTextOnly)
return;
RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
ASSERT(textRenderer);
if (!textShouldBePainted(textRenderer))
return;
RenderStyle* style = parentRenderer->style();
ASSERT(style);
paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer->scaledFont(), true);
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
bool hasFill = svgStyle->hasFill();
bool hasVisibleStroke = svgStyle->hasVisibleStroke();
RenderStyle* selectionStyle = style;
if (hasSelection) {
selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION);
if (selectionStyle) {
const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle();
ASSERT(svgSelectionStyle);
if (!hasFill)
hasFill = svgSelectionStyle->hasFill();
if (!hasVisibleStroke)
hasVisibleStroke = svgSelectionStyle->hasVisibleStroke();
} else
selectionStyle = style;
}
if (textRenderer->frame() && textRenderer->frame()->view() && textRenderer->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) {
hasFill = true;
hasVisibleStroke = false;
}
AffineTransform fragmentTransform;
unsigned textFragmentsSize = m_textFragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
SVGTextFragment& fragment = m_textFragments.at(i);
ASSERT(!m_paintingResource);
GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
fragment.buildFragmentTransform(fragmentTransform);
if (!fragmentTransform.isIdentity()) {
stateSaver.save();
paintInfo.context->concatCTM(fragmentTransform);
}
// Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations.
unsigned decorations = style->textDecorationsInEffect();
if (decorations & TextDecorationUnderline)
paintDecoration(paintInfo.context, TextDecorationUnderline, fragment);
if (decorations & TextDecorationOverline)
paintDecoration(paintInfo.context, TextDecorationOverline, fragment);
for (int i = 0; i < 3; i++) {
switch (svgStyle->paintOrderType(i)) {
case PT_FILL:
// Fill text
if (hasFill) {
m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode;
paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
}
break;
case PT_STROKE:
// Stroke text
if (hasVisibleStroke) {
m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode;
paintText(paintInfo.context, style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
}
break;
case PT_MARKERS:
// Markers don't apply to text
break;
default:
ASSERT_NOT_REACHED();
break;
}
}
//.........这里部分代码省略.........