layout/mathml/nsMathMLmpaddedFrame.cpp

Wed, 31 Dec 2014 07:53:36 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:53:36 +0100
branch
TOR_BUG_3246
changeset 5
4ab42b5ab56c
permissions
-rw-r--r--

Correct small whitespace inconsistency, lost while renaming variables.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6
michael@0 7 #include "nsMathMLmpaddedFrame.h"
michael@0 8 #include "nsMathMLElement.h"
michael@0 9 #include "mozilla/gfx/2D.h"
michael@0 10 #include <algorithm>
michael@0 11
michael@0 12 //
michael@0 13 // <mpadded> -- adjust space around content - implementation
michael@0 14 //
michael@0 15
michael@0 16 #define NS_MATHML_SIGN_INVALID -1 // if the attribute is not there
michael@0 17 #define NS_MATHML_SIGN_UNSPECIFIED 0
michael@0 18 #define NS_MATHML_SIGN_MINUS 1
michael@0 19 #define NS_MATHML_SIGN_PLUS 2
michael@0 20
michael@0 21 #define NS_MATHML_PSEUDO_UNIT_UNSPECIFIED 0
michael@0 22 #define NS_MATHML_PSEUDO_UNIT_ITSELF 1 // special
michael@0 23 #define NS_MATHML_PSEUDO_UNIT_WIDTH 2
michael@0 24 #define NS_MATHML_PSEUDO_UNIT_HEIGHT 3
michael@0 25 #define NS_MATHML_PSEUDO_UNIT_DEPTH 4
michael@0 26 #define NS_MATHML_PSEUDO_UNIT_NAMEDSPACE 5
michael@0 27
michael@0 28 nsIFrame*
michael@0 29 NS_NewMathMLmpaddedFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
michael@0 30 {
michael@0 31 return new (aPresShell) nsMathMLmpaddedFrame(aContext);
michael@0 32 }
michael@0 33
michael@0 34 NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmpaddedFrame)
michael@0 35
michael@0 36 nsMathMLmpaddedFrame::~nsMathMLmpaddedFrame()
michael@0 37 {
michael@0 38 }
michael@0 39
michael@0 40 NS_IMETHODIMP
michael@0 41 nsMathMLmpaddedFrame::InheritAutomaticData(nsIFrame* aParent)
michael@0 42 {
michael@0 43 // let the base class get the default from our parent
michael@0 44 nsMathMLContainerFrame::InheritAutomaticData(aParent);
michael@0 45
michael@0 46 mPresentationData.flags |= NS_MATHML_STRETCH_ALL_CHILDREN_VERTICALLY;
michael@0 47
michael@0 48 return NS_OK;
michael@0 49 }
michael@0 50
michael@0 51 void
michael@0 52 nsMathMLmpaddedFrame::ProcessAttributes()
michael@0 53 {
michael@0 54 /*
michael@0 55 parse the attributes
michael@0 56
michael@0 57 width = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
michael@0 58 height = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
michael@0 59 depth = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
michael@0 60 lspace = [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | h-unit | namedspace)
michael@0 61 voffset= [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | v-unit | namedspace)
michael@0 62 */
michael@0 63
michael@0 64 nsAutoString value;
michael@0 65
michael@0 66 // width
michael@0 67 mWidthSign = NS_MATHML_SIGN_INVALID;
michael@0 68 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::width, value);
michael@0 69 if (!value.IsEmpty()) {
michael@0 70 if (!ParseAttribute(value, mWidthSign, mWidth, mWidthPseudoUnit)) {
michael@0 71 ReportParseError(nsGkAtoms::width->GetUTF16String(), value.get());
michael@0 72 }
michael@0 73 }
michael@0 74
michael@0 75 // height
michael@0 76 mHeightSign = NS_MATHML_SIGN_INVALID;
michael@0 77 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::height, value);
michael@0 78 if (!value.IsEmpty()) {
michael@0 79 if (!ParseAttribute(value, mHeightSign, mHeight, mHeightPseudoUnit)) {
michael@0 80 ReportParseError(nsGkAtoms::height->GetUTF16String(), value.get());
michael@0 81 }
michael@0 82 }
michael@0 83
michael@0 84 // depth
michael@0 85 mDepthSign = NS_MATHML_SIGN_INVALID;
michael@0 86 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::depth_, value);
michael@0 87 if (!value.IsEmpty()) {
michael@0 88 if (!ParseAttribute(value, mDepthSign, mDepth, mDepthPseudoUnit)) {
michael@0 89 ReportParseError(nsGkAtoms::depth_->GetUTF16String(), value.get());
michael@0 90 }
michael@0 91 }
michael@0 92
michael@0 93 // lspace
michael@0 94 mLeadingSpaceSign = NS_MATHML_SIGN_INVALID;
michael@0 95 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::lspace_, value);
michael@0 96 if (!value.IsEmpty()) {
michael@0 97 if (!ParseAttribute(value, mLeadingSpaceSign, mLeadingSpace,
michael@0 98 mLeadingSpacePseudoUnit)) {
michael@0 99 ReportParseError(nsGkAtoms::lspace_->GetUTF16String(), value.get());
michael@0 100 }
michael@0 101 }
michael@0 102
michael@0 103 // voffset
michael@0 104 mVerticalOffsetSign = NS_MATHML_SIGN_INVALID;
michael@0 105 mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::voffset_, value);
michael@0 106 if (!value.IsEmpty()) {
michael@0 107 if (!ParseAttribute(value, mVerticalOffsetSign, mVerticalOffset,
michael@0 108 mVerticalOffsetPseudoUnit)) {
michael@0 109 ReportParseError(nsGkAtoms::voffset_->GetUTF16String(), value.get());
michael@0 110 }
michael@0 111 }
michael@0 112
michael@0 113 }
michael@0 114
michael@0 115 // parse an input string in the following format (see bug 148326 for testcases):
michael@0 116 // [+|-] unsigned-number (% [pseudo-unit] | pseudo-unit | css-unit | namedspace)
michael@0 117 bool
michael@0 118 nsMathMLmpaddedFrame::ParseAttribute(nsString& aString,
michael@0 119 int32_t& aSign,
michael@0 120 nsCSSValue& aCSSValue,
michael@0 121 int32_t& aPseudoUnit)
michael@0 122 {
michael@0 123 aCSSValue.Reset();
michael@0 124 aSign = NS_MATHML_SIGN_INVALID;
michael@0 125 aPseudoUnit = NS_MATHML_PSEUDO_UNIT_UNSPECIFIED;
michael@0 126 aString.CompressWhitespace(); // aString is not a const in this code
michael@0 127
michael@0 128 int32_t stringLength = aString.Length();
michael@0 129 if (!stringLength)
michael@0 130 return false;
michael@0 131
michael@0 132 nsAutoString number, unit;
michael@0 133
michael@0 134 //////////////////////
michael@0 135 // see if the sign is there
michael@0 136
michael@0 137 int32_t i = 0;
michael@0 138
michael@0 139 if (aString[0] == '+') {
michael@0 140 aSign = NS_MATHML_SIGN_PLUS;
michael@0 141 i++;
michael@0 142 }
michael@0 143 else if (aString[0] == '-') {
michael@0 144 aSign = NS_MATHML_SIGN_MINUS;
michael@0 145 i++;
michael@0 146 }
michael@0 147 else
michael@0 148 aSign = NS_MATHML_SIGN_UNSPECIFIED;
michael@0 149
michael@0 150 // get the number
michael@0 151 bool gotDot = false, gotPercent = false;
michael@0 152 for (; i < stringLength; i++) {
michael@0 153 char16_t c = aString[i];
michael@0 154 if (gotDot && c == '.') {
michael@0 155 // error - two dots encountered
michael@0 156 aSign = NS_MATHML_SIGN_INVALID;
michael@0 157 return false;
michael@0 158 }
michael@0 159
michael@0 160 if (c == '.')
michael@0 161 gotDot = true;
michael@0 162 else if (!nsCRT::IsAsciiDigit(c)) {
michael@0 163 break;
michael@0 164 }
michael@0 165 number.Append(c);
michael@0 166 }
michael@0 167
michael@0 168 // catch error if we didn't enter the loop above... we could simply initialize
michael@0 169 // floatValue = 1, to cater for cases such as width="height", but that wouldn't
michael@0 170 // be in line with the spec which requires an explicit number
michael@0 171 if (number.IsEmpty()) {
michael@0 172 aSign = NS_MATHML_SIGN_INVALID;
michael@0 173 return false;
michael@0 174 }
michael@0 175
michael@0 176 nsresult errorCode;
michael@0 177 float floatValue = number.ToFloat(&errorCode);
michael@0 178 if (NS_FAILED(errorCode)) {
michael@0 179 aSign = NS_MATHML_SIGN_INVALID;
michael@0 180 return false;
michael@0 181 }
michael@0 182
michael@0 183 // see if this is a percentage-based value
michael@0 184 if (i < stringLength && aString[i] == '%') {
michael@0 185 i++;
michael@0 186 gotPercent = true;
michael@0 187 }
michael@0 188
michael@0 189 // the remainder now should be a css-unit, or a pseudo-unit, or a named-space
michael@0 190 aString.Right(unit, stringLength - i);
michael@0 191
michael@0 192 if (unit.IsEmpty()) {
michael@0 193 if (gotPercent) {
michael@0 194 // case ["+"|"-"] unsigned-number "%"
michael@0 195 aCSSValue.SetPercentValue(floatValue / 100.0f);
michael@0 196 aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
michael@0 197 return true;
michael@0 198 } else {
michael@0 199 // case ["+"|"-"] unsigned-number
michael@0 200 // XXXfredw: should we allow non-zero unitless values? See bug 757703.
michael@0 201 if (!floatValue) {
michael@0 202 aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
michael@0 203 aPseudoUnit = NS_MATHML_PSEUDO_UNIT_ITSELF;
michael@0 204 return true;
michael@0 205 }
michael@0 206 }
michael@0 207 }
michael@0 208 else if (unit.EqualsLiteral("width")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_WIDTH;
michael@0 209 else if (unit.EqualsLiteral("height")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_HEIGHT;
michael@0 210 else if (unit.EqualsLiteral("depth")) aPseudoUnit = NS_MATHML_PSEUDO_UNIT_DEPTH;
michael@0 211 else if (!gotPercent) { // percentage can only apply to a pseudo-unit
michael@0 212
michael@0 213 // see if the unit is a named-space
michael@0 214 if (nsMathMLElement::ParseNamedSpaceValue(unit, aCSSValue,
michael@0 215 nsMathMLElement::
michael@0 216 PARSE_ALLOW_NEGATIVE)) {
michael@0 217 // re-scale properly, and we know that the unit of the named-space is 'em'
michael@0 218 floatValue *= aCSSValue.GetFloatValue();
michael@0 219 aCSSValue.SetFloatValue(floatValue, eCSSUnit_EM);
michael@0 220 aPseudoUnit = NS_MATHML_PSEUDO_UNIT_NAMEDSPACE;
michael@0 221 return true;
michael@0 222 }
michael@0 223
michael@0 224 // see if the input was just a CSS value
michael@0 225 // We are not supposed to have a unitless, percent, negative or namedspace
michael@0 226 // value here.
michael@0 227 number.Append(unit); // leave the sign out if it was there
michael@0 228 if (nsMathMLElement::ParseNumericValue(number, aCSSValue,
michael@0 229 nsMathMLElement::
michael@0 230 PARSE_SUPPRESS_WARNINGS, nullptr))
michael@0 231 return true;
michael@0 232 }
michael@0 233
michael@0 234 // if we enter here, we have a number that will act as a multiplier on a pseudo-unit
michael@0 235 if (aPseudoUnit != NS_MATHML_PSEUDO_UNIT_UNSPECIFIED) {
michael@0 236 if (gotPercent)
michael@0 237 aCSSValue.SetPercentValue(floatValue / 100.0f);
michael@0 238 else
michael@0 239 aCSSValue.SetFloatValue(floatValue, eCSSUnit_Number);
michael@0 240
michael@0 241 return true;
michael@0 242 }
michael@0 243
michael@0 244
michael@0 245 #ifdef DEBUG
michael@0 246 printf("mpadded: attribute with bad numeric value: %s\n",
michael@0 247 NS_LossyConvertUTF16toASCII(aString).get());
michael@0 248 #endif
michael@0 249 // if we reach here, it means we encounter an unexpected input
michael@0 250 aSign = NS_MATHML_SIGN_INVALID;
michael@0 251 return false;
michael@0 252 }
michael@0 253
michael@0 254 void
michael@0 255 nsMathMLmpaddedFrame::UpdateValue(int32_t aSign,
michael@0 256 int32_t aPseudoUnit,
michael@0 257 const nsCSSValue& aCSSValue,
michael@0 258 const nsHTMLReflowMetrics& aDesiredSize,
michael@0 259 nscoord& aValueToUpdate) const
michael@0 260 {
michael@0 261 nsCSSUnit unit = aCSSValue.GetUnit();
michael@0 262 if (NS_MATHML_SIGN_INVALID != aSign && eCSSUnit_Null != unit) {
michael@0 263 nscoord scaler = 0, amount = 0;
michael@0 264
michael@0 265 if (eCSSUnit_Percent == unit || eCSSUnit_Number == unit) {
michael@0 266 switch(aPseudoUnit) {
michael@0 267 case NS_MATHML_PSEUDO_UNIT_WIDTH:
michael@0 268 scaler = aDesiredSize.Width();
michael@0 269 break;
michael@0 270
michael@0 271 case NS_MATHML_PSEUDO_UNIT_HEIGHT:
michael@0 272 scaler = aDesiredSize.TopAscent();
michael@0 273 break;
michael@0 274
michael@0 275 case NS_MATHML_PSEUDO_UNIT_DEPTH:
michael@0 276 scaler = aDesiredSize.Height() - aDesiredSize.TopAscent();
michael@0 277 break;
michael@0 278
michael@0 279 default:
michael@0 280 // if we ever reach here, it would mean something is wrong
michael@0 281 // somewhere with the setup and/or the caller
michael@0 282 NS_ERROR("Unexpected Pseudo Unit");
michael@0 283 return;
michael@0 284 }
michael@0 285 }
michael@0 286
michael@0 287 if (eCSSUnit_Number == unit)
michael@0 288 amount = NSToCoordRound(float(scaler) * aCSSValue.GetFloatValue());
michael@0 289 else if (eCSSUnit_Percent == unit)
michael@0 290 amount = NSToCoordRound(float(scaler) * aCSSValue.GetPercentValue());
michael@0 291 else
michael@0 292 amount = CalcLength(PresContext(), mStyleContext, aCSSValue);
michael@0 293
michael@0 294 if (NS_MATHML_SIGN_PLUS == aSign)
michael@0 295 aValueToUpdate += amount;
michael@0 296 else if (NS_MATHML_SIGN_MINUS == aSign)
michael@0 297 aValueToUpdate -= amount;
michael@0 298 else
michael@0 299 aValueToUpdate = amount;
michael@0 300 }
michael@0 301 }
michael@0 302
michael@0 303 nsresult
michael@0 304 nsMathMLmpaddedFrame::Reflow(nsPresContext* aPresContext,
michael@0 305 nsHTMLReflowMetrics& aDesiredSize,
michael@0 306 const nsHTMLReflowState& aReflowState,
michael@0 307 nsReflowStatus& aStatus)
michael@0 308 {
michael@0 309 ProcessAttributes();
michael@0 310
michael@0 311 ///////////////
michael@0 312 // Let the base class format our content like an inferred mrow
michael@0 313 nsresult rv = nsMathMLContainerFrame::Reflow(aPresContext, aDesiredSize,
michael@0 314 aReflowState, aStatus);
michael@0 315 //NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status");
michael@0 316 return rv;
michael@0 317 }
michael@0 318
michael@0 319 /* virtual */ nsresult
michael@0 320 nsMathMLmpaddedFrame::Place(nsRenderingContext& aRenderingContext,
michael@0 321 bool aPlaceOrigin,
michael@0 322 nsHTMLReflowMetrics& aDesiredSize)
michael@0 323 {
michael@0 324 nsresult rv =
michael@0 325 nsMathMLContainerFrame::Place(aRenderingContext, false, aDesiredSize);
michael@0 326 if (NS_MATHML_HAS_ERROR(mPresentationData.flags) || NS_FAILED(rv)) {
michael@0 327 DidReflowChildren(GetFirstPrincipalChild());
michael@0 328 return rv;
michael@0 329 }
michael@0 330
michael@0 331 nscoord height = aDesiredSize.TopAscent();
michael@0 332 nscoord depth = aDesiredSize.Height() - aDesiredSize.TopAscent();
michael@0 333 // The REC says:
michael@0 334 //
michael@0 335 // "The lspace attribute ('leading' space) specifies the horizontal location
michael@0 336 // of the positioning point of the child content with respect to the
michael@0 337 // positioning point of the mpadded element. By default they coincide, and
michael@0 338 // therefore absolute values for lspace have the same effect as relative
michael@0 339 // values."
michael@0 340 //
michael@0 341 // "MathML renderers should ensure that, except for the effects of the
michael@0 342 // attributes, the relative spacing between the contents of the mpadded
michael@0 343 // element and surrounding MathML elements would not be modified by replacing
michael@0 344 // an mpadded element with an mrow element with the same content, even if
michael@0 345 // linebreaking occurs within the mpadded element."
michael@0 346 //
michael@0 347 // (http://www.w3.org/TR/MathML/chapter3.html#presm.mpadded)
michael@0 348 //
michael@0 349 // "In those discussions, the terms leading and trailing are used to specify
michael@0 350 // a side of an object when which side to use depends on the directionality;
michael@0 351 // ie. leading means left in LTR but right in RTL."
michael@0 352 // (http://www.w3.org/TR/MathML/chapter3.html#presm.bidi.math)
michael@0 353 nscoord lspace = 0;
michael@0 354 // In MathML3, "width" will be the bounding box width and "advancewidth" will
michael@0 355 // refer "to the horizontal distance between the positioning point of the
michael@0 356 // mpadded and the positioning point for the following content". MathML2
michael@0 357 // doesn't make the distinction.
michael@0 358 nscoord width = aDesiredSize.Width();
michael@0 359 nscoord voffset = 0;
michael@0 360
michael@0 361 int32_t pseudoUnit;
michael@0 362 nscoord initialWidth = width;
michael@0 363
michael@0 364 // update width
michael@0 365 pseudoUnit = (mWidthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
michael@0 366 ? NS_MATHML_PSEUDO_UNIT_WIDTH : mWidthPseudoUnit;
michael@0 367 UpdateValue(mWidthSign, pseudoUnit, mWidth,
michael@0 368 aDesiredSize, width);
michael@0 369 width = std::max(0, width);
michael@0 370
michael@0 371 // update "height" (this is the ascent in the terminology of the REC)
michael@0 372 pseudoUnit = (mHeightPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
michael@0 373 ? NS_MATHML_PSEUDO_UNIT_HEIGHT : mHeightPseudoUnit;
michael@0 374 UpdateValue(mHeightSign, pseudoUnit, mHeight,
michael@0 375 aDesiredSize, height);
michael@0 376 height = std::max(0, height);
michael@0 377
michael@0 378 // update "depth" (this is the descent in the terminology of the REC)
michael@0 379 pseudoUnit = (mDepthPseudoUnit == NS_MATHML_PSEUDO_UNIT_ITSELF)
michael@0 380 ? NS_MATHML_PSEUDO_UNIT_DEPTH : mDepthPseudoUnit;
michael@0 381 UpdateValue(mDepthSign, pseudoUnit, mDepth,
michael@0 382 aDesiredSize, depth);
michael@0 383 depth = std::max(0, depth);
michael@0 384
michael@0 385 // update lspace
michael@0 386 if (mLeadingSpacePseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
michael@0 387 pseudoUnit = mLeadingSpacePseudoUnit;
michael@0 388 UpdateValue(mLeadingSpaceSign, pseudoUnit, mLeadingSpace,
michael@0 389 aDesiredSize, lspace);
michael@0 390 }
michael@0 391
michael@0 392 // update voffset
michael@0 393 if (mVerticalOffsetPseudoUnit != NS_MATHML_PSEUDO_UNIT_ITSELF) {
michael@0 394 pseudoUnit = mVerticalOffsetPseudoUnit;
michael@0 395 UpdateValue(mVerticalOffsetSign, pseudoUnit, mVerticalOffset,
michael@0 396 aDesiredSize, voffset);
michael@0 397 }
michael@0 398 // do the padding now that we have everything
michael@0 399 // The idea here is to maintain the invariant that <mpadded>...</mpadded> (i.e.,
michael@0 400 // with no attributes) looks the same as <mrow>...</mrow>. But when there are
michael@0 401 // attributes, tweak our metrics and move children to achieve the desired visual
michael@0 402 // effects.
michael@0 403
michael@0 404 if ((StyleVisibility()->mDirection ?
michael@0 405 mWidthSign : mLeadingSpaceSign) != NS_MATHML_SIGN_INVALID) {
michael@0 406 // there was padding on the left. dismiss the left italic correction now
michael@0 407 // (so that our parent won't correct us)
michael@0 408 mBoundingMetrics.leftBearing = 0;
michael@0 409 }
michael@0 410
michael@0 411 if ((StyleVisibility()->mDirection ?
michael@0 412 mLeadingSpaceSign : mWidthSign) != NS_MATHML_SIGN_INVALID) {
michael@0 413 // there was padding on the right. dismiss the right italic correction now
michael@0 414 // (so that our parent won't correct us)
michael@0 415 mBoundingMetrics.width = width;
michael@0 416 mBoundingMetrics.rightBearing = mBoundingMetrics.width;
michael@0 417 }
michael@0 418
michael@0 419 nscoord dx = (StyleVisibility()->mDirection ?
michael@0 420 width - initialWidth - lspace : lspace);
michael@0 421
michael@0 422 aDesiredSize.SetTopAscent(height);
michael@0 423 aDesiredSize.Width() = mBoundingMetrics.width;
michael@0 424 aDesiredSize.Height() = depth + aDesiredSize.TopAscent();
michael@0 425 mBoundingMetrics.ascent = height;
michael@0 426 mBoundingMetrics.descent = depth;
michael@0 427 aDesiredSize.mBoundingMetrics = mBoundingMetrics;
michael@0 428
michael@0 429 mReference.x = 0;
michael@0 430 mReference.y = aDesiredSize.TopAscent();
michael@0 431
michael@0 432 if (aPlaceOrigin) {
michael@0 433 // Finish reflowing child frames, positioning their origins.
michael@0 434 PositionRowChildFrames(dx, aDesiredSize.TopAscent() - voffset);
michael@0 435 }
michael@0 436
michael@0 437 return NS_OK;
michael@0 438 }
michael@0 439
michael@0 440 /* virtual */ nsresult
michael@0 441 nsMathMLmpaddedFrame::MeasureForWidth(nsRenderingContext& aRenderingContext,
michael@0 442 nsHTMLReflowMetrics& aDesiredSize)
michael@0 443 {
michael@0 444 ProcessAttributes();
michael@0 445 return Place(aRenderingContext, false, aDesiredSize);
michael@0 446 }

mercurial