static void ProcessTranslatePart(float& aResult, const nsCSSValue& aValue, nsStyleContext* aContext, nsPresContext* aPresContext, PRBool& aCanStoreInRuleTree, nscoord aSize, float aAppUnitsPerMatrixUnit) { nscoord offset = 0; float percent = 0.0f; if (aValue.GetUnit() == eCSSUnit_Percent) { percent = aValue.GetPercentValue(); } else if (aValue.IsCalcUnit()) { nsRuleNode::ComputedCalc result = nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext, aCanStoreInRuleTree); percent = result.mPercent; offset = result.mLength; } else { offset = CalcLength(aValue, aContext, aPresContext, aCanStoreInRuleTree); } aResult = (percent * NSAppUnitsToFloatPixels(aSize, aAppUnitsPerMatrixUnit)) + NSAppUnitsToFloatPixels(offset, aAppUnitsPerMatrixUnit); }
static void SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aStart, nsStyleAnimation::Value& aEnd, Animatable* aValue) { nsStyleAnimation::Value interpolatedValue; NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() || aStart.GetUnit() == nsStyleAnimation::eUnit_None || aEnd.GetUnit() == nsStyleAnimation::eUnit_None, "Must have same unit"); nsStyleAnimation::Interpolate(aAnimation.property(), aStart, aEnd, aPortion, interpolatedValue); if (aAnimation.property() == eCSSProperty_opacity) { *aValue = interpolatedValue.GetFloatValue(); return; } nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue(); TransformData& data = aAnimation.data().get_TransformData(); nsPoint origin = data.origin(); // we expect all our transform data to arrive in css pixels, so here we must // adjust to dev pixels. double cssPerDev = double(nsDeviceContext::AppUnitsPerCSSPixel()) / double(data.appUnitsPerDevPixel()); gfxPoint3D mozOrigin = data.mozOrigin(); mozOrigin.x = mozOrigin.x * cssPerDev; mozOrigin.y = mozOrigin.y * cssPerDev; gfxPoint3D perspectiveOrigin = data.perspectiveOrigin(); perspectiveOrigin.x = perspectiveOrigin.x * cssPerDev; perspectiveOrigin.y = perspectiveOrigin.y * cssPerDev; nsDisplayTransform::FrameTransformProperties props(interpolatedList, mozOrigin, perspectiveOrigin, data.perspective()); gfx3DMatrix transform = nsDisplayTransform::GetResultingTransformMatrix(props, origin, data.appUnitsPerDevPixel(), &data.bounds()); gfxPoint3D scaledOrigin = gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(origin.x, data.appUnitsPerDevPixel())), NS_round(NSAppUnitsToFloatPixels(origin.y, data.appUnitsPerDevPixel())), 0.0f); transform.Translate(scaledOrigin); InfallibleTArray<TransformFunction> functions; functions.AppendElement(TransformMatrix(transform)); *aValue = functions; }
float ProcessTranslatePart(const nsCSSValue& aValue, nsStyleContext* aContext, nsPresContext* aPresContext, RuleNodeCacheConditions& aConditions, TransformReferenceBox* aRefBox, TransformReferenceBox::DimensionGetter aDimensionGetter) { nscoord offset = 0; float percent = 0.0f; if (aValue.GetUnit() == eCSSUnit_Percent) { percent = aValue.GetPercentValue(); } else if (aValue.GetUnit() == eCSSUnit_Pixel || aValue.GetUnit() == eCSSUnit_Number) { // Handle this here (even though nsRuleNode::CalcLength handles it // fine) so that callers are allowed to pass a null style context // and pres context to SetToTransformFunction if they know (as // StyleAnimationValue does) that all lengths within the transform // function have already been computed to pixels and percents. // // Raw numbers are treated as being pixels. // // Don't convert to aValue to AppUnits here to avoid precision issues. return aValue.GetFloatValue(); } else if (aValue.IsCalcUnit()) { nsRuleNode::ComputedCalc result = nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext, aConditions); percent = result.mPercent; offset = result.mLength; } else { offset = nsRuleNode::CalcLength(aValue, aContext, aPresContext, aConditions); } float translation = NSAppUnitsToFloatPixels(offset, nsPresContext::AppUnitsPerCSSPixel()); // We want to avoid calling aDimensionGetter if there's no percentage to be // resolved (for performance reasons - see TransformReferenceBox). if (percent != 0.0f && aRefBox) { translation += percent * NSAppUnitsToFloatPixels((aRefBox->*aDimensionGetter)(), nsPresContext::AppUnitsPerCSSPixel()); } return translation; }
/* GetThebesMatrix converts the stored matrix in a few steps. */ gfxMatrix nsStyleTransformMatrix::GetThebesMatrix(const nsRect& aBounds, float aScale) const { /* Compute the graphics matrix. We take the stored main elements, along with * the delta, and add in the matrices: * * | 0 0 dx1| * | 0 0 dx2| * width * | 0 0 0| * * | 0 0 dy1| * | 0 0 dy2| * height * | 0 0 0| */ return gfxMatrix(mMain[0], mMain[1], mMain[2], mMain[3], NSAppUnitsToFloatPixels(GetXTranslation(aBounds), aScale), NSAppUnitsToFloatPixels(GetYTranslation(aBounds), aScale)); }
bool LayerTransactionParent::RecvGetTransform(PLayerParent* aParent, gfx3DMatrix* aTransform) { if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { return false; } // The following code recovers the untranslated transform // from the shadow transform by undoing the translations in // AsyncCompositionManager::SampleValue. Layer* layer = cast(aParent)->AsLayer(); if (!layer) { return false; } gfx::To3DMatrix(layer->AsLayerComposite()->GetShadowTransform(), *aTransform); if (ContainerLayer* c = layer->AsContainerLayer()) { aTransform->ScalePost(1.0f/c->GetInheritedXScale(), 1.0f/c->GetInheritedYScale(), 1.0f); } float scale = 1; gfxPoint3D scaledOrigin; gfxPoint3D transformOrigin; for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) { if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) { const TransformData& data = layer->GetAnimations()[i].data().get_TransformData(); scale = data.appUnitsPerDevPixel(); scaledOrigin = gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)), NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)), 0.0f); transformOrigin = data.transformOrigin(); break; } } aTransform->Translate(-scaledOrigin); *aTransform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - transformOrigin, *aTransform); return true; }
FILE* operator<<(FILE* out, const nsRect& rect) { nsAutoString tmp; // Output the coordinates in fractional pixels so they're easier to read tmp.Append('{'); tmp.AppendFloat(NSAppUnitsToFloatPixels(rect.x, nsDeviceContext::AppUnitsPerCSSPixel())); tmp.AppendLiteral(", "); tmp.AppendFloat(NSAppUnitsToFloatPixels(rect.y, nsDeviceContext::AppUnitsPerCSSPixel())); tmp.AppendLiteral(", "); tmp.AppendFloat(NSAppUnitsToFloatPixels(rect.width, nsDeviceContext::AppUnitsPerCSSPixel())); tmp.AppendLiteral(", "); tmp.AppendFloat(NSAppUnitsToFloatPixels(rect.height, nsDeviceContext::AppUnitsPerCSSPixel())); tmp.Append('}'); fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out); return out; }
float ProcessTranslatePart(const nsCSSValue& aValue, nsStyleContext* aContext, nsPresContext* aPresContext, bool& aCanStoreInRuleTree, nscoord aSize) { nscoord offset = 0; float percent = 0.0f; if (aValue.GetUnit() == eCSSUnit_Percent) { percent = aValue.GetPercentValue(); } else if (aValue.GetUnit() == eCSSUnit_Pixel || aValue.GetUnit() == eCSSUnit_Number) { // Handle this here (even though nsRuleNode::CalcLength handles it // fine) so that callers are allowed to pass a null style context // and pres context to SetToTransformFunction if they know (as // StyleAnimationValue does) that all lengths within the transform // function have already been computed to pixels and percents. // // Raw numbers are treated as being pixels. // // Don't convert to aValue to AppUnits here to avoid precision issues. return aValue.GetFloatValue(); } else if (aValue.IsCalcUnit()) { nsRuleNode::ComputedCalc result = nsRuleNode::SpecifiedCalcToComputedCalc(aValue, aContext, aPresContext, aCanStoreInRuleTree); percent = result.mPercent; offset = result.mLength; } else { offset = nsRuleNode::CalcLength(aValue, aContext, aPresContext, aCanStoreInRuleTree); } return (percent * NSAppUnitsToFloatPixels(aSize, nsPresContext::AppUnitsPerCSSPixel())) + NSAppUnitsToFloatPixels(offset, nsPresContext::AppUnitsPerCSSPixel()); }
void nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue) { // Convert from nscoord to pt. // // Note: according to IA2, "The conversion doesn't have to be exact. // The intent is to give the user a feel for the size of the text." // // ATK does not specify a unit and will likely follow IA2 here. // // XXX todo: consider sharing this code with layout module? (bug 474621) float px = NSAppUnitsToFloatPixels(aValue, nsDeviceContext::AppUnitsPerCSSPixel()); // Each pt is 4/3 of a CSS pixel. int pts = NS_lround(px*3/4); nsAutoString value; value.AppendInt(pts); value.Append(NS_LITERAL_STRING("pt")); aFormattedValue = value; }
bool LayerTransactionParent::RecvGetAnimationTransform(PLayerParent* aParent, MaybeTransform* aTransform) { if (mDestroyed || !layer_manager() || layer_manager()->IsDestroyed()) { return false; } Layer* layer = cast(aParent)->AsLayer(); if (!layer) { return false; } // This method is specific to transforms applied by animation. // This is because this method uses the information stored with an animation // such as the origin of the reference frame corresponding to the layer, to // recover the untranslated transform from the shadow transform. For // transforms that are not set by animation we don't have this information // available. if (!layer->AsLayerComposite()->GetShadowTransformSetByAnimation()) { *aTransform = mozilla::void_t(); return true; } // The following code recovers the untranslated transform // from the shadow transform by undoing the translations in // AsyncCompositionManager::SampleValue. Matrix4x4 transform = layer->AsLayerComposite()->GetShadowTransform(); if (ContainerLayer* c = layer->AsContainerLayer()) { // Undo the scale transform applied by AsyncCompositionManager::SampleValue transform.ScalePost(1.0f/c->GetInheritedXScale(), 1.0f/c->GetInheritedYScale(), 1.0f); } float scale = 1; gfxPoint3D scaledOrigin; gfxPoint3D transformOrigin; for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) { if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) { const TransformData& data = layer->GetAnimations()[i].data().get_TransformData(); scale = data.appUnitsPerDevPixel(); scaledOrigin = gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)), NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)), 0.0f); double cssPerDev = double(nsDeviceContext::AppUnitsPerCSSPixel()) / double(scale); transformOrigin = data.transformOrigin() * cssPerDev; break; } } // Undo the translation to the origin of the reference frame applied by // AsyncCompositionManager::SampleValue transform.Translate(-scaledOrigin.x, -scaledOrigin.y, -scaledOrigin.z); // Undo the rebasing applied by // nsDisplayTransform::GetResultingTransformMatrixInternal gfxPoint3D basis = -scaledOrigin - transformOrigin; transform.ChangeBasis(basis.x, basis.y, basis.z); // Convert to CSS pixels (this undoes the operations performed by // nsStyleTransformMatrix::ProcessTranslatePart which is called from // nsDisplayTransform::GetResultingTransformMatrix) double devPerCss = double(scale) / double(nsDeviceContext::AppUnitsPerCSSPixel()); transform._41 *= devPerCss; transform._42 *= devPerCss; transform._43 *= devPerCss; *aTransform = transform; return true; }